修改 x 轴下方凌乱和重叠的日期标签的最优雅方法? (Seaborn,条形图)

Posted

技术标签:

【中文标题】修改 x 轴下方凌乱和重叠的日期标签的最优雅方法? (Seaborn,条形图)【英文标题】:The most elegant way to modify messy and overlapping date labels below x axis? (Seaborn, barplot) 【发布时间】:2019-04-30 20:51:23 【问题描述】:

df (Pandas DataFrame) 有两列:Date (as datetime64) 和 Amount (as float)。

我使用 barplot 绘制 Amount 列中的值与时间的关系:

sns.barplot(x="Date", y="Amount", data=df)
plt.show()

但是,日期标签一团糟(见图)。在 Pandas 中处理这个问题的优雅方式是什么?我正在考虑从标签中删除月份和年份,或者将标签旋转 90 度。这些将如何完成,或者有更好的选择吗?谢谢。

【问题讨论】:

Rotate label text in seaborn factorplot的可能重复 旋转标签显示 barplot 以以下格式显示日期标签:“2018-09-29T00:00:00.000000000”,即使 print(df["Date"] 以正确的格式显示它们格式(2018-09-29)(不知道为什么?)。这是造成混乱的原因之一,但我认为最初的问题仍然存在。 这绝对是一个单独的问题,“我怎样才能让 pandas 将我的日期时间格式化为日期”(这里很可能已经有了答案——天真地,你可以使用映射到你的 strftime df 行)。 当然这是一个单独的问题,但是这样做(在另一个回复的帮助下)并没有完全解决标签凌乱的问题。旋转帮助了一些,较小的字体帮助更多,最后只显示日期(而不是日期)使标签可读。谢谢。 【参考方案1】:

这会自动调整 SNS 图的日期 x 轴,因此在大多数情况下您不必手动执行此操作: sns_plot.get_figure().autofmt_xdate()

【讨论】:

在答案中包含完整的代码。 “sns_plot”是您创建的一个局部变量,作为 seaborn 绘图函数的返回值。此修改更改了日期时间的角度,但如果这也导致重叠,它不会消除时间信息。 被低估的答案 这解决了我的问题。谢谢!!【参考方案2】:

我会同时做:旋转您的 xlabels 并仅使用日期:

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()

【讨论】:

谢谢,这很好地清理了标签。我不确定“plt.xticks()[0]”是做什么的,我应该将这些日期标签称为 xticks 或标签或其他名称吗? plt.xticks()[0] 是获取当前绘图的刻度位置的一种方法(还有其他方法)。因此,您将原始刻度位置、标签作为格式化字符串以及所需的旋转传递给 xticks attribute【参考方案3】:

另一种解决方案,如果您有大量日期并且希望以更稀疏的间隔标记它们;

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

还值得考虑使用 seaborn 绘图默认值,并将日期放在 y 轴上以便于阅读,但这更多是个人喜好。

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

【讨论】:

以上是关于修改 x 轴下方凌乱和重叠的日期标签的最优雅方法? (Seaborn,条形图)的主要内容,如果未能解决你的问题,请参考以下文章

Highcharts - 日期时间轴标签重叠

Matplotlib绘图时x轴标签重叠的解决办法

Python,x轴标题与matplotlib中的刻度标签重叠

R语言ggplot2可视化轴标签重叠问题解决实战:修改轴标签字体轴标签垂直于坐标轴(或者旋转特定角度)

如何防止 sns.countplot 中的 x 轴标签重叠

如何使用 nvd3 在柱形图上定位旋转的 x 轴标签?