Python 熊猫图:周末使用单独的颜色,x轴上的打印时间相当长

Python 熊猫图:周末使用单独的颜色,x轴上的打印时间相当长,python,matplotlib,pandas,time-series,Python,Matplotlib,Pandas,Time Series,我创造了一个情节,看起来像 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

我创造了一个情节,看起来像

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)
我有几个问题:

  • 我怎样才能具体地展示周末。我想的一些方法是抓取周末对应的指数,然后在XLIM之间绘制透明条。同样,也可以为相同的对象绘制矩形。如果能在熊猫身上清楚地做到这一点,那将是最好的
  • 日期格式不是最漂亮的
  • 以下是用于生成此绘图的代码

    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,我尝试使用主要的格式化程序和定位器,代码如下:

    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);
    
    产出如下:

    了解数据帧的外观可能会有所帮助

    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)
    
    [122]中的
    :df4
    出[122]:
    日期时间索引:36个条目,2011-04-19 00:00:00至2011-05-24 00:00:00
    数据列:
    (0到6 AM)与19个非空值
    (下午12点至6点)黄昏19非空值
    (6到中午12点)上午19个非空值
    (下午6点到中午12点)夜间20个非空值
    数据类型:float64(4)
    
    我做了很多尝试,现在这些黑客技术很管用。等待一个更具吸引力和一致性的解决方案。 标签问题的解决方案:

    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
    
    def find_weekend_索引(日期时间数组):
    指数=[]
    对于范围内的i(len(datetime_数组)):
    如果datetime_数组[i].weekday()>=5:
    索引.附加(i)
    回报指数
    def突出显示周末(周末指数,ax):
    i=0
    
    虽然我现在Pandas在每个系列上都支持强大的
    .dt
    名称空间,但是可以在没有任何显式Python循环的情况下确定每个周末的开始和结束时间。只需使用
    t.dt.dayofweek>=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
    轴,它将为您突出显示周末

    在matplotlib中实现这一点并不复杂,例如,用另一种颜色标记周末的标签是一种公认的解决方案。使用matplotlibs
    WeekdayLocator
    归档周末simpy。我个人认为,如果在matplotlib而不是pandas中绘制绘图,那么定制绘图就更容易了。@nordev:将此添加到下面的解决方案中,该解决方案现在位于社区Wiki中。我建议使用
    ax.axvspan(周末索引[I]、周末索引[I]+2,facecolor='green',edgecolor='none',alpha=.2)
    来创建绿色“填充”,因为不必明确指定
    ymax
    @nordev:谢谢。只有在替换
    index.append(i)
    by
    index.append(datetime\u数组[i])时,时间序列对象才有帮助
    。鉴于
    import datetime as dt
    的常见用法,我是否可以建议不要使用
    dt
    作为变量,这会使它变得模糊。@yeliabsalohcin有趣的想法-我已经重命名了该变量。我们将看看是否有人对可读性有任何抱怨。