【问题标题】:How to highlight a plotline chart with vertical color bar for specific weekdays (saturday and sunday)? [duplicate]如何突出显示特定工作日(周六和周日)的带有垂直颜色条的绘图线图? [复制]
【发布时间】:2020-12-06 17:21:40
【问题描述】:

我为航班绘制了每日线图,我想突出显示所有周六和周日。我正在尝试用 axvspan 来做,但我在努力使用它?关于如何编码的任何建议?

(flights.loc[flights['date'].dt.month.between(1, 2), 'date']
         .dt.to_period('D')
         .value_counts()
         .sort_index()
         .plot(kind="line",figsize=(12,6))
 )

提前感谢您提供的任何帮助

【问题讨论】:

  • 有一些非常相似的问题herehere

标签: python pandas matplotlib plot plotly


【解决方案1】:

使用 pandas 时间戳类型的日期列,您可以直接使用 pandas.Timestamp.weekday 获取日期的星期几。然后您可以使用df.iterrows() 来检查每个日期是周六还是周日,并在图中包含如下形状:

for index, row in df.iterrows():
    if row['date'].weekday() == 5 or row['date'].weekday() == 6:
        fig.add_shape(...)

通过这样的设置,您会得到一条指示每个日期是星期六还是星期日的行。但鉴于您正在处理一个连续的时间序列,将这些时期说明为整个时期的一个区域而不是突出每一天可能是有意义的。因此,只需确定每个星期六并将整个期间设置为每个星期六加上 pd.DateOffset(1) 即可:

带有示例数据的完整代码

# imports
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
import datetime

pd.set_option('display.max_rows', None)

# data sample
cols = ['signal']
nperiods = 20
np.random.seed(12)
df = pd.DataFrame(np.random.randint(-2, 2, size=(nperiods, len(cols))),
                  columns=cols)
datelist = pd.date_range(datetime.datetime(2020, 1, 1).strftime('%Y-%m-%d'),periods=nperiods).tolist()
df['date'] = datelist 
df = df.set_index(['date'])
df.index = pd.to_datetime(df.index)
df.iloc[0] = 0
df = df.cumsum().reset_index()
df['signal'] = df['signal'] + 100

# plotly setup
fig = px.line(df, x='date', y=df.columns[1:])
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,255,0.1)')
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,255,0.1)')

for index, row in df.iterrows():
    if row['date'].weekday() == 5: #or row['date'].weekday() == 6:
        fig.add_shape(type="rect",
                        xref="x",
                        yref="paper",
                        x0=row['date'],
                        y0=0,
#                         x1=row['date'],
                        x1=row['date'] + pd.DateOffset(1),
                        y1=1,
                        line=dict(color="rgba(0,0,0,0)",width=3,),
                        fillcolor="rgba(0,0,0,0.1)",
                        layer='below') 
fig.show()

【讨论】:

    【解决方案2】:

    您可以使用 pandas 的 dt.weekday 来获取与给定日期的工作日对应的整数。 5 等于星期六,6 等于星期日(星期一为 0)。您可以将此信息用作对数据框进行切片并过滤属于周六或周日的条目的另一种方法。正如您所提到的,它们可以使用 axvspan 突出显示,并且 matplotlib 版本 >3 能够使用 datetime 对象作为输入。 1 天必须通过datetime.timedelta 添加,因为如果xmin=xmax 将不会绘制矩形。 这是代码

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import datetime
    
    #create sample data and dataframe
    datelist = pd.date_range(start="2014-12-09",end="2015-03-02").tolist()
    datelist += datelist #test to see whether it works with multiple entries having the same date
    flights = pd.DataFrame(datelist, columns=["date"])
    
    #plot command, save object in variable
    plot = flights.loc[flights['date'].dt.month.between(1, 2), 'date'].dt.to_period('D').value_counts().sort_index().plot(kind="line",figsize=(12,6))
    
    #filter out saturdays and sundays from the date range needed
    weekends = flights.loc[(flights['date'].dt.month.between(1, 2)) & ((flights['date'].dt.weekday == 5) | (flights['date'].dt.weekday == 6)), 'date']
    #5 = Saturday, 6 = Sunday
    
    #plot axvspan for every sat or sun, set() to get unique dates
    for day in set(weekends.tolist()):
        plot.axvspan(day, day + datetime.timedelta(days=1))
    

    【讨论】:

      猜你喜欢
      • 2020-04-02
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-08
      • 1970-01-01
      • 2014-12-12
      相关资源
      最近更新 更多