问题
df (Pandas DataFrame) has two columns: Date (as datetime64) and Amount (as float).
I plot the values from Amount column against time, using barplot:
sns.barplot(x="Date", y="Amount", data=df)
plt.show()
However, the date labels are a terrible mess (see picture). What would be an elegant way of dealing with this in Pandas? I'm considering removing month and year from the label, or rotating the labels 90 degrees. How would these be done, or is there a better option? Thank you.
回答1:
I would do both: rotate your xlabels and use only the dates:
import seaborn as sns
import matplotlib.pyplot as plt
# dummy data:
df = pd.DataFrame({'Date':pd.to_datetime(['1999-12-12', '2000-12-12', '2001-12-12']),'Amount':[1,2,3]})
sns.barplot(x="Date", y="Amount", data=df)
# use the original locations of your xticks, and only the date for your label
# rotate the labels 90 degrees using the rotation argument
plt.xticks(plt.xticks()[0], df.Date.dt.date, rotation=90)
plt.tight_layout()
plt.show()
回答2:
Another solution, if you have a large number of dates and would prefer to label them at a more sparse interval;
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# dummy data:
df = pd.DataFrame({'Date':pd.to_datetime(['1999-12-12', '2000-12-12', '2001-12-12',
'2002-12-12', '2003-12-12', '2004-12-12',
'2005-12-12','2006-12-12', '2007-12-12', '2008-12-12']),
'Amount':[1,2,3,4,5,6,7,8,9,10]})
fig, ax = plt.subplots()
sns.barplot(x="Date", y="Amount", data=df, ax=ax)
# set the frequency for labelling the xaxis
freq = int(2)
# set the xlabels as the datetime data for the given labelling frequency,
# also use only the date for the label
ax.set_xticklabels(df.iloc[::freq].Date.dt.date)
# set the xticks at the same frequency as the xlabels
xtix = ax.get_xticks()
ax.set_xticks(xtix[::freq])
# nicer label format for dates
fig.autofmt_xdate()
plt.tight_layout()
plt.show()
Click to see plot
It's also worth considering using the seaborn plot defaults, and placing the dates on the yaxis for ease of reading, but that's moreso personal preference.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# set the seaborn asthetics
sns.set()
# dummy data:
df = pd.DataFrame({'Date':pd.to_datetime(['1999-12-12', '2000-12-12', '2001-12-12',
'2002-12-12', '2003-12-12', '2004-12-12',
'2005-12-12','2006-12-12', '2007-12-12', '2008-12-12']),
'Amount':[1,2,3,4,5,6,7,8,9,10]})
fig, ax = plt.subplots()
# plot with a horizontal orientation
sns.barplot(y="Date", x="Amount", data=df, ax=ax, orient='h')
# set the frequency for labelling the yaxis
freq = int(2)
# set the ylabels as the datetime data for the given labelling frequency,
# also use only the date for the label
ax.set_yticklabels(df.iloc[::freq].Date.dt.date)
# set the yticks at the same frequency as the ylabels
ytix = ax.get_yticks()
ax.set_yticks(ytix[::freq])
plt.tight_layout()
plt.show()
Click to see nicer plot
来源:https://stackoverflow.com/questions/53528054/the-most-elegant-way-to-modify-messy-and-overlapping-date-labels-below-x-axis