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
Matplotlib show x-ticks on all subplots and unique y label
提问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:
当前图表输出:
采纳答案by DavidG
There are a couple of things you can do. Either remove sharex = True
. Or, if you want to use that, sharex
sets the x ticks to not be visible i.e. set_visible(False)
. Therefore, you can set them to True
to 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:
这使:
回答by tmdavison
As other answers have mentioned, to get the ylabel
showing up on both subplots, you can use the object-oriented interface here axes[0].set_ylabel
and axes[1].set_ylabel
.
正如其他答案所提到的,要ylabel
在两个子图中都显示出来,您可以使用面向对象的界面 hereaxes[0].set_ylabel
和axes[1].set_ylabel
。
You should also use .tick_params
on 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)
回答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.subplots
replacing
现在,到 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=True
from fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True)
to have separate x-axis.
删除sharex=True
从fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True)
具有独立的x轴。
For ylabels
对于 ylabels
axes[0].set_ylabel('Pop')
axes[1].set_ylabel('Temp')