pandas Matplotlib 在所有子图上显示 x-ticks 和唯一的 y 标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46912100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 04:41:18  来源:igfitidea点击:

Matplotlib show x-ticks on all subplots and unique y label

pythonpandasmatplotlibsubplot

提问by MBasith

I am plotting two subplots that share the same x-axis but when I plot I only see the x-axis ticks on the second subplot. How can I make the x-ticks visible on both subplots?

我正在绘制共享相同 x 轴的两个子图,但是当我绘制时,我只看到第二个子图上的 x 轴刻度。如何使两个子图上的 x-ticks 都可见?

Also I would like to set y-labels for both subplots but only the second is visible. Can you please help in displaying the y-label on both subplots?

此外,我想为两个子图设置 y 标签,但只有第二个可见。你能帮忙在两个子图上显示 y 标签吗?

Below is my reproducible code.

下面是我的可重现代码。

#!/usr/bin/python3
import pandas as pd
desired_width = 1500
pd.set_option('display.width', desired_width)
import matplotlib.pyplot as plt
import numpy as np


df = pd.DataFrame([{'DATETIME': '2017-09-29 01:00,', 'Population': 1000, 'Temp': 90, 'State': 'California'},
                   {'DATETIME': '2017-09-29 01:00,', 'Population': 2000, 'Temp': 70, 'State': 'Illinois'},
                   {'DATETIME': '2017-09-29 01:00,', 'Population': 3000, 'Temp': 50, 'State': 'Georgia'},
                   {'DATETIME': '2017-09-29 02:00,', 'Population': 2000, 'Temp': 40, 'State': 'California'},
                   {'DATETIME': '2017-09-29 02:00,', 'Population': 6000, 'Temp': 20, 'State': 'Illinois'},
                   {'DATETIME': '2017-09-29 02:00,', 'Population': 4000, 'Temp': 30, 'State': 'Georgia'},
                   {'DATETIME': '2017-09-29 03:00,', 'Population': 3000, 'Temp': 40, 'State': 'California'},
                   {'DATETIME': '2017-09-29 03:00,', 'Population': 4000, 'Temp': 60, 'State': 'Illinois'},
                   {'DATETIME': '2017-09-29 03:00,', 'Population': 2000, 'Temp': 80, 'State': 'Georgia'}])

df.index = df['DATETIME']
df.index = (pd.to_datetime(df.index)).strftime("%m/%d %H:00")

fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True)

df.groupby('State')['Population'].plot(kind='line', linestyle='--', alpha=0.5, marker='o', legend=True, ax=axes[0])
plt.ylabel('Pop')
df.groupby('State')['Temp'].plot(kind='line', linestyle='--', alpha=0.5, marker='o', legend=True, ax=axes[1])
plt.ylabel('Temp')
plt.tick_params(axis='both', which='both', labelsize=7)
plt.tight_layout()
plt.show()

Current Chart Output:

当前图表输出:

enter image description here

在此处输入图片说明

采纳答案by DavidG

There are a couple of things you can do. Either remove sharex = True. Or, if you want to use that, sharexsets the x ticks to not be visible i.e. set_visible(False). Therefore, you can set them to Trueto stop this.

您可以做几件事。要么删除sharex = True. 或者,如果您想使用它, sharex请将 x 刻度设置为不可见,即set_visible(False)。因此,您可以将它们设置True为停止此操作。

In order to have the subplots formatted the same, you need to set the tick params for each subplot by using axes[0].tick_params(axis='both', which='both', labelsize=7)for both subplots (i.e. repeat for axes[1])

为了使子图的格式相同,您需要使用axes[0].tick_params(axis='both', which='both', labelsize=7)for 两个子图为每个子图设置刻度参数(即重复 for axes[1]

Note, personally I prefer to use matpotlib object oriented API i.e using ax.set_ylabel()rather than plt.ylabel()as I think it gives more control over which subplots and axes you are using. Therefore I have slightly modified your code in that regards too

请注意,我个人更喜欢使用 matpotlib 面向对象的 API,即使用ax.set_ylabel()而不是plt.ylabel()因为我认为它可以更好地控制您正在使用的子图和轴。因此,我在这方面也稍微修改了您的代码

df = pd.DataFrame([{'DATETIME': '2017-09-29 01:00,', 'Population': 1000, 'Temp': 90, 'State': 'California'},
                   {'DATETIME': '2017-09-29 01:00,', 'Population': 2000, 'Temp': 70, 'State': 'Illinois'},
                   {'DATETIME': '2017-09-29 01:00,', 'Population': 3000, 'Temp': 50, 'State': 'Georgia'},
                   {'DATETIME': '2017-09-29 02:00,', 'Population': 2000, 'Temp': 40, 'State': 'California'},
                   {'DATETIME': '2017-09-29 02:00,', 'Population': 6000, 'Temp': 20, 'State': 'Illinois'},
                   {'DATETIME': '2017-09-29 02:00,', 'Population': 4000, 'Temp': 30, 'State': 'Georgia'},
                   {'DATETIME': '2017-09-29 03:00,', 'Population': 3000, 'Temp': 40, 'State': 'California'},
                   {'DATETIME': '2017-09-29 03:00,', 'Population': 4000, 'Temp': 60, 'State': 'Illinois'},
                   {'DATETIME': '2017-09-29 03:00,', 'Population': 2000, 'Temp': 80, 'State': 'Georgia'}])

df.index = df['DATETIME']
df.index = (pd.to_datetime(df.index)).strftime("%m/%d %H:00")

fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True)

df.groupby('State')['Population'].plot(kind='line', linestyle='--', alpha=0.5, marker='o', legend=True, ax=axes[0])
axes[0].set_ylabel('Pop')
df.groupby('State')['Temp'].plot(kind='line', linestyle='--', alpha=0.5, marker='o', legend=True, ax=axes[1])
axes[1].set_ylabel('Temp')

# Set the formatting the same for both subplots
axes[0].tick_params(axis='both', which='both', labelsize=7)
axes[1].tick_params(axis='both', which='both', labelsize=7)

# set ticks visible, if using sharex = True. Not needed otherwise
for tick in axes[0].get_xticklabels():
    tick.set_visible(True)

plt.tight_layout()
plt.show()

Which gives:

这使:

enter image description here

在此处输入图片说明

回答by tmdavison

As other answers have mentioned, to get the ylabelshowing up on both subplots, you can use the object-oriented interface here axes[0].set_ylabeland axes[1].set_ylabel.

正如其他答案所提到的,要ylabel在两个子图中都显示出来,您可以使用面向对象的界面 hereaxes[0].set_ylabelaxes[1].set_ylabel

You should also use .tick_paramson both axes to get the same size tick labels, etc. for both subplots

您还应该.tick_params在两个轴上使用以获得两个子图的相同大小的刻度标签等

And finally, to get the tick labels to show up on the first subplot, as an alternative to looping over all the ticks and having to set them to be visible, you can achieve the same thing by giving just one more option tick_params: labelbottom=True.

最后,为了让刻度标签显示在第一个子图上,作为循环所有刻度并必须将它们设置为可见的替代方法,您可以通过再提供一个选项来实现相同的目的 tick_params: labelbottom=True

fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True)

df.groupby('State')['Population'].plot(kind='line', linestyle='--', alpha=0.5, marker='o', legend=True, ax=axes[0])
axes[0].set_ylabel('Pop')
df.groupby('State')['Temp'].plot(kind='line', linestyle='--', alpha=0.5, marker='o', legend=True, ax=axes[1])
axes[1].set_ylabel('Temp')
axes[0].tick_params(axis='both', which='both', labelsize=7, labelbottom=True)
axes[1].tick_params(axis='both', which='both', labelsize=7)

enter image description here

在此处输入图片说明

回答by Ignacio Vergara Kausel

Regarding the first question, I'd advise against that not to clutter the plot with extra ink.

关于第一个问题,我建议不要用多余的墨水弄乱情节。

Now, onto the y labels. you have to use the axes you get from plt.subplotsreplacing

现在,到 y 标签上。您必须使用从plt.subplots替换中获得的轴

plt.ylabel('Pop')by axes[0].set_ylabel('Pop')and plt.ylabel('Pop')by axes[1].set_ylabel('Temp')

plt.ylabel('Pop')通过axes[0].set_ylabel('Pop')plt.ylabel('Pop')通过axes[1].set_ylabel('Temp')

回答by Karl Anka

Remove sharex=Truefrom fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True)to have separate x-axis.

删除sharex=Truefig, axes = plt.subplots(nrows=2, ncols=1, sharex=True)具有独立的x轴。

For ylabels

对于 ylabels

axes[0].set_ylabel('Pop')
axes[1].set_ylabel('Temp')