Issue
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?
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?
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:
Solution
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.
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]
)
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
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:
Answered By - DavidG
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.