【问题标题】:Pandas Plots: Separate color for weekends, pretty printing times on x axisPandas Plots:周末的单独颜色,x 轴上漂亮的打印时间
【发布时间】:2013-05-05 00:26:31
【问题描述】:

我创建了一个看起来像的情节

我有几个问题:

  1. 我怎样才能特别显示周末。我曾想过的一些方法是获取与周末相对应的索引,然后在 xlims 之间绘制透明条。也可以绘制相同的矩形。最好能在 Pandas 中简单地完成。
  2. 日期格式不是最漂亮的

以下是用于生成此图的代码

ax4=df4.plot(kind='bar',stacked=True,title='Mains 1 Breakdown');
ax4.set_ylabel('Power (W)');
idx_weekend=df4.index[df4.index.dayofweek>=5]
ax.bar(idx_weekend.to_datetime(),[1800 for x in range(10)])

ax.bar 专门用于突出显示周末,但它不会产生任何可见的输出。 (问题 1) 对于问题 2,我尝试使用 Major Formatter 和 Locators,代码如下:

ax4=df4.plot(kind='bar',stacked=True,title='Mains 1 Breakdown');
ax4.set_ylabel('Power (W)');
formatter=matplotlib.dates.DateFormatter('%d-%b');
locator=matplotlib.dates.DayLocator(interval=1);
ax4.xaxis.set_major_formatter(formatter);
ax4.xaxis.set_major_locator(locator);

产生的输出如下:

了解 Dataframe 的样子可能会有所帮助

In [122]:df4

Out[122]:
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 36 entries, 2011-04-19 00:00:00 to 2011-05-24 00:00:00
Data columns:
(0 to 6 AM) Dawn          19  non-null values
(12 to 6 PM) Dusk         19  non-null values
(6 to 12 Noon) Morning    19  non-null values
(6PM to 12 Noon) Night    20  non-null values
dtypes: float64(4)

【问题讨论】:

  • 在 matplotlib 中实现这一点并不是很复杂,例如用另一种颜色标记周末的刻度标签是一种公认​​的解决方案。要归档周末,请使用 matplotlibs WeekdayLocator。就我个人而言,我认为如果在 matplotlib 而不是 pandas 中绘制绘图,自定义绘图会更容易。
  • @nordev:也将此添加到下面的解决方案中,该解决方案现在位于社区 wiki 中

标签: python matplotlib pandas time-series


【解决方案1】:

我尝试了很多,现在这些技巧有效。等待更 Pythonic 和一致的解决方案。 标注问题的解决方案:

def correct_labels(ax):
    labels = [item.get_text() for item in ax.get_xticklabels()]
    days=[label.split(" ")[0] for label in labels]
    months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
    final_labels=[]
    for i in range(len(days)):
        a=days[i].split("-")
        final_labels.append(a[2]+"\n"+months[int(a[1])-1])
    ax.set_xticklabels(final_labels)

另外,在绘图时,我进行了以下更改

ax=df.plot(kind='bar',rot=0)

这会使标签旋转为 0。

为了找到周末并突出显示它们,我编写了以下两个函数:

def find_weekend_indices(datetime_array):
    indices=[]
    for i in range(len(datetime_array)):
        if datetime_array[i].weekday()>=5:
            indices.append(i)
    return indices

def highlight_weekend(weekend_indices,ax):
    i=0
    while i<len(weekend_indices):
         ax.axvspan(weekend_indices[i], weekend_indices[i]+2, facecolor='green', edgecolor='none', alpha=.2)
         i+=2

现在,该图看起来更加有用,并且涵盖了这些用例。

【讨论】:

  • 我建议使用ax.axvspan(weekend_indices[i], weekend_indices[i]+2, facecolor='green', edgecolor='none', alpha=.2) 来创建绿色“填充物”,因为不必明确指定ymax
  • @nordev:谢谢。这有帮助
  • 仅在将 indices.append(i) 替换为 indices.append(datetime_array[i]) 时适用于时间序列对象。
【解决方案2】:

现在 Pandas 在每个系列中都支持强大的 .dt 命名空间,因此无需任何显式 Python 循环即可识别每个周末的开始和结束。只需使用t.dt.dayofweek &gt;= 5 过滤您的时间值以仅选择周末的时间,然后按每周不同的虚构值分组 - 这里我使用year * 100 + weekofyear,因为结果看起来像201603,这是相当的易于阅读以进行调试。

得到的函数是:

def highlight_weekends(ax, timeseries):
    d = timeseries.dt
    ranges = timeseries[d.dayofweek >= 5].groupby(d.year * 100 + d.weekofyear).agg(['min', 'max'])
    for i, tmin, tmax in ranges.itertuples():
        ax.axvspan(tmin, tmax, facecolor='orange', edgecolor='none', alpha=0.1)

只需将轴和作为您的x 轴的时间序列传递给它,它就会为您突出显示周末!

【讨论】:

  • 鉴于import datetime as dt 的常见用法,我可以建议不要将dt 用作变量,这会掩盖它。
  • @yeliabsalohcin 有趣的想法——我已经重命名了变量。我们会看看是否有任何关于可读性的投诉。
猜你喜欢
  • 2013-12-07
  • 1970-01-01
  • 2011-04-05
  • 2017-05-26
  • 2018-10-23
  • 1970-01-01
  • 2021-06-22
  • 2015-02-07
  • 1970-01-01
相关资源
最近更新 更多