pandas 条形图更改日期格式 [英] Pandas bar plot changes date format

查看:149
本文介绍了 pandas 条形图更改日期格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的堆积线图,它具有使用以下代码时要神奇设置的日期格式.

I have a simple stacked line plot that has exactly the date format I want magically set when using the following code.

df_ts = df.resample("W", how='max')
df_ts.plot(figsize=(12,8), stacked=True)

但是,当绘制与条形图相同的数据时,日期会神秘地转换为丑陋且难以读取的格式.

However, the dates mysteriously transform themselves to an ugly and unreadable format when plotting the same data as a bar plot.

df_ts = df.resample("W", how='max')
df_ts.plot(kind='bar', figsize=(12,8), stacked=True)

将原始数据进行了一些转换,使其具有每周的最大值.为什么自动设置日期发生这种根本性变化?如何获得上面格式正确的日期?

The original data was transformed a bit to have the weekly max. Why is this radical change in automatically set dates happening? How can I have the nicely formatted dates as above?

这是一些虚拟数据

start = pd.to_datetime("1-1-2012")
idx = pd.date_range(start, periods= 365).tolist()
df=pd.DataFrame({'A':np.random.random(365), 'B':np.random.random(365)})
df.index = idx
df_ts = df.resample('W', how= 'max')
df_ts.plot(kind='bar', stacked=True)

推荐答案

该绘图代码假定条形图中的每个条都应具有其自己的标签. 您可以通过指定自己的格式化程序来覆盖此假设:

The plotting code assumes that each bar in a bar plot deserves its own label. You could override this assumption by specifying your own formatter:

ax.xaxis.set_major_formatter(formatter)

熊猫使用的pandas.tseries.converter.TimeSeries_DateFormatter 格式化好"图中的日期与线图一起使用时, x值是日期.但是,使用条形图的x值(至少是 TimeSeries_DateFormatter.__call__接收到的只是整数 为零.如果尝试将TimeSeries_DateFormatter与条形图一起使用,则所有标签都将从1970-1-1 UTC时期开始,因为这是对应于零的日期.因此,不幸的是,用于折线图的格式化程序对bar毫无用处 情节(至少据我所知).

The pandas.tseries.converter.TimeSeries_DateFormatter that Pandas uses to format the dates in the "good" plot works well with line plots when the x-values are dates. However, with a bar plot the x-values (at least those received by TimeSeries_DateFormatter.__call__) are merely integers starting at zero. If you try to use TimeSeries_DateFormatter with a bar plot, all the labels thus start at the Epoch, 1970-1-1 UTC, since this is the date which corresponds to zero. So the formatter used for line plots is unfortunately useless for bar plots (at least as far as I can see).

我看到的产生所需格式的最简单方法是显式生成并设置标签:

The easiest way I see to produce the desired formatting is to generate and set the labels explicitly:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.ticker as ticker

start = pd.to_datetime("5-1-2012")
idx = pd.date_range(start, periods= 365)
df = pd.DataFrame({'A':np.random.random(365), 'B':np.random.random(365)})
df.index = idx
df_ts = df.resample('W', how= 'max')

ax = df_ts.plot(kind='bar', x=df_ts.index, stacked=True)

# Make most of the ticklabels empty so the labels don't get too crowded
ticklabels = ['']*len(df_ts.index)
# Every 4th ticklable shows the month and day
ticklabels[::4] = [item.strftime('%b %d') for item in df_ts.index[::4]]
# Every 12th ticklabel includes the year
ticklabels[::12] = [item.strftime('%b %d\n%Y') for item in df_ts.index[::12]]
ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
plt.gcf().autofmt_xdate()

plt.show()

产量

对于那些寻找带有日期的条形图的简单示例的人:

For those looking for a simple example of a bar plot with dates:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker

dates = pd.date_range('2012-1-1', '2017-1-1', freq='M')
df = pd.DataFrame({'A':np.random.random(len(dates)), 'Date':dates})
fig, ax = plt.subplots()
df.plot.bar(x='Date', y='A', ax=ax)
ticklabels = ['']*len(df)
skip = len(df)//12
ticklabels[::skip] = df['Date'].iloc[::skip].dt.strftime('%Y-%m-%d')
ax.xaxis.set_major_formatter(mticker.FixedFormatter(ticklabels))
fig.autofmt_xdate()

# fixes the tracker
# https://matplotlib.org/users/recipes.html
def fmt(x, pos=0, max_i=len(ticklabels)-1):
    i = int(x) 
    i = 0 if i < 0 else max_i if i > max_i else i
    return dates[i]
ax.fmt_xdata = fmt
plt.show()

这篇关于 pandas 条形图更改日期格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆