我能够通过使用我的绘图数据来绘制折线图,但x轴行情指示器显示不正确。因为我的数据框具有period
datetimeindex
对象,所以我想沿x轴正确显示它们。我尝试了一些有关axis ticker
的现有帖子,但仍然没有正确的情节。如何解决?任何想法?谢谢
EDA数据
我的尝试:
这是我目前的尝试:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
df = pd.read_csv('plot_data.csv', encoding='utf-8')
df.div(df.Total, axis=0).applymap(lambda x: f'{x * 100:.2f}%')
fig, ax1 = plt.subplots(figsize=(14,6))
_ = df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, ax=ax1, marker='o',ls='--')
ax1.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
ax1.xaxis.set_major_locator(mdates.DayLocator())
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d-%Y'))
plt.show()
目标
我想绘制一个折线图,其中y轴应正确显示百分比,而x轴应正确显示沿年的时间段。在我的代码中,x轴行情显示不正确。有什么主意吗?
最简单的方法是让熊猫去做。为了在x轴上显示日期,熊猫喜欢将这些日期作为索引。只需执行df.set_index('quarter', inplace=True)
。
[有了这样的索引,熊猫将设置一个看起来像日期的x轴,但实际上是一个类别轴(编号为0、1、2、3,...),其中熊猫提供了刻度标签。
要设置百分比,请使用PercentFormatter
,并带有参数来设置100%(设置为1,而不是默认值100)和小数位数。
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as mtick
filename = 'plot_data.csv'
df = pd.read_csv(filename, encoding='utf-8')
df.set_index('quarter', inplace=True)
fig, ax1 = plt.subplots(figsize=(14, 6))
df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, marker='o', ls='--')
ax1.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
plt.xticks(range(len(df.index)), df.index, rotation=90)
plt.show()
或者,您可以将索引转换为matplotlib日期,并使用matplotlib的格式和定位符:
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as mtick
filename = 'plot_data.csv'
df = pd.read_csv(filename, encoding='utf-8')
df.quarter = [pd.to_datetime(d).date() for d in df.quarter]
df.set_index('quarter', inplace=True)
fig, ax1 = plt.subplots(figsize=(14, 6))
_ = df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, marker='o', ls='--')
ax1.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
ax1.xaxis.set_major_locator(mdates.MonthLocator(bymonthday=1, interval=3))
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d-%Y'))
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
[quarter
列已转换为datetime
格式,然后设置为索引:
import matplotlib.dates as mdates
df = pd.read_csv('plot_data.csv', encoding='utf-8')
df['quarter'] = pd.to_datetime(df['quarter'], format='%Y-%m-%d')
df = df.set_index(df['quarter'])
df = df.sort_index()
fig, ax1 = plt.subplots(figsize=(14,6))
_ = df.drop('quarter', axis=1).div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1)
ax1.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
ax1.set_xticks(df.index)
ax1.xaxis_date()
plt.show()
在与matplotlib斗争之后,我找到了使用seaborn的解决方案。
import matplotlib.ticker as mtick
import seaborn as sns
sns.set()
df = pd.read_csv('plot_data.csv', encoding='utf-8')
df['quarter'] = pd.to_datetime(df['quarter'], format='%Y-%m-%d')
df = df.set_index(df['quarter'])
df = df.sort_index()
df_clean = df.drop('quarter', axis=1).div(df.Total, axis=0)
df_clean.drop('Total', axis=1, inplace=True)
df_us = df_clean.unstack().reset_index().copy()
df_us = df_us.rename(columns={'level_0':'Country', 0:'Percent'})
g = sns.lineplot(data=df_us, x='quarter', y='Percent', hue='Country')
g.set(xticks=df.index)
plt.xticks(rotation=30)
g.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
plt.savefig('sns.png')
plt.show()