【问题标题】:pandas dataframe : seaborn plot bar with multiple columns and datetime as index熊猫数据框:以多列和日期时间为索引的seaborn绘图栏
【发布时间】:2020-08-29 02:52:45
【问题描述】:

我有两列这样的数据框(以日期为索引):

我的目标是像这样(使用 excel)用 seaborn 绘制条形图:

我关注了这里的讨论: enter link description here

我知道我必须使用 melt 。但是当我输入以下代码时,结果是索引(日期)消失(被数字替换)并且数据框结构改变如下:

# pd.melt(df, id_vars=['A'], value_vars=['B'])
premier_melt = pd.melt(final_mada_df,id_vars=["Confirmed"],value_vars = ["Recovered"])

我们怎样才能解决这种问题来正确地用seaborn绘制条形图

提前致谢


我按照以下建议将代码放在下面:

# main dataframe 
  df2
       Recovered Confirmed
3/20/20   0          3
3/21/20   0          0
3/22/20   0          0
3/23/20   0          9

df2.stack()

出来:

3/20/20  Recovered    0
         Confirmed    3
3/21/20  Recovered    0
         Confirmed    0
3/22/20  Recovered    0
                     ..
5/4/20   Confirmed    0
5/5/20   Recovered    2
         Confirmed    2
5/6/20   Recovered    0
         Confirmed    7
Length: 96, dtype: int64

df2.rename(columns={'level_1':'Status',0:'Values'})

出来:

       Recovered Confirmed
3/20/20   0         3
3/21/20   0         0
3/22/20   0         0
3/23/20   0         9
3/24/20   0         5

但是当我输入以下代码时,出现错误:

# plot 
ax = sns.barplot(x=df2.index,y='Values',data=df2,hue='Status')

ValueError: Could not interpret input 'Values'

【问题讨论】:

    标签: python pandas seaborn


    【解决方案1】:

    使用.stack(),如下图。

    import pandas as pd
    import seaborn as sns
    import numpy as np
    from datetime import datetime
    import matplotlib.pyplot as plt
    
    # optional graph format parameters
    plt.rcParams['figure.figsize'] = (16.0, 10.0)
    plt.style.use('ggplot')
    
    # data
    np.random.seed(365)
    data = {'Confirmed': [np.random.randint(10) for _ in range(25)],
            'date': pd.bdate_range(datetime.today(), freq='d', periods=25).tolist()}
    
    # dataframe
    df = pd.DataFrame(data)
    
    # add recovered
    df['Recovered'] = df['Confirmed'].div(2)
    
    | date                |   Confirmed |   Recovered |
    |:--------------------|------------:|------------:|
    | 2020-05-12 00:00:00 |           4 |         2   |
    | 2020-05-13 00:00:00 |           1 |         0.5 |
    | 2020-05-14 00:00:00 |           5 |         2.5 |
    | 2020-05-15 00:00:00 |           1 |         0.5 |
    | 2020-05-16 00:00:00 |           9 |         4.5 |
    
    # verify datetime format and set index
    df.date = pd.to_datetime(df.date)
    df.set_index('date', inplace=True)
    

    转换数据

    • 需要这种转换才能从 seaborn 获得所需的地块
    df1 = df.stack().reset_index().set_index('date').rename(columns={'level_1': 'Status', 0: 'Values'})
    
    | date                | Status    |   Values |
    |:--------------------|:----------|---------:|
    | 2020-05-23 00:00:00 | Confirmed |        2 |
    | 2020-05-23 00:00:00 | Recovered |        1 |
    | 2020-05-24 00:00:00 | Confirmed |        4 |
    | 2020-05-24 00:00:00 | Recovered |        2 |
    | 2020-05-25 00:00:00 | Confirmed |        1 |
    

    Seaborn 情节

    • 格式化 x 轴刻度标签需要使用 df 而不是 df1。如上所示,每个日期都重复,因此df1.index.to_series() 将生成一个包含重复日期的列表。
    ax = sns.barplot(x=df1.index, y='Values', data=df1, hue='Status')
    
    # format the x-axis tick labels uses df, not df1
    ax.xaxis.set_major_formatter(plt.FixedFormatter(df.index.to_series().dt.strftime("%Y-%m-%d")))
    
    # alternative use the following to format the labels
    # _, labels = plt.xticks()
    # labels = [label.get_text()[:10] for label in labels]
    # ax.xaxis.set_major_formatter(plt.FixedFormatter(labels))
    
    plt.xticks(rotation=90)
    plt.show()
    

    或者df.plot.bar()

    • 生成与上面相同的图,但不转换为df1
    • df 有一个日期时间索引,它被识别为 x 轴,所有列都绘制在 y 轴上。
    ax = df.plot.bar()
    ax.xaxis.set_major_formatter(plt.FixedFormatter(df.index.to_series().dt.strftime("%Y-%m-%d")))
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2017-02-08
      • 2021-05-03
      • 2021-03-19
      • 2012-12-27
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 2021-05-20
      • 1970-01-01
      相关资源
      最近更新 更多