【问题标题】:Horizontal bar plot for categories over the time一段时间内类别的水平条形图
【发布时间】:2020-08-07 22:47:06
【问题描述】:

我目前有一个数据集,其中每一行有效或无效,该有效性由 True 或 False 列声明。

数据集的示例可以在下面的 sn-p 上可视化:

                TimeStamp  Avg. Values  ... Validity
0     2015-02-14 20:30:00      5.1736  ...     False  
1     2015-02-14 20:40:00      16.6266  ...    True   
2     2015-02-14 20:50:00      12.7667  ...    True   
3     2015-02-14 21:00:00      11.6077  ...    False   
4     2015-02-14 21:10:00       19.6851  ...   True   
                  ...          ...  ...         ...    
1000 2015-06-12 23:30:00       1.699  ...      True  
1001 2015-06-12 23:40:00       2.2468  ...     False  
1002 2015-06-12 23:50:00       3.1147  ...     False  
1003 2015-06-13 00:00:00       6.141  ...      True  
1004 2015-06-13 00:10:00       3.792  ...      True  

考虑到列的有效性,我的目标是在一段时间内像甘特图一样绘制有效性。所以我的想法是,我会生成水平条,指示随着时间的推移数据的类别。我编造的一个例子并没有反映上面的数据,但它说明了我想要实现的目标是:

目前我看到的大多数水平条形图只显示每个类别的数据量。那么,是否有可能像甘特图一样绘制它,随着时间的推移显示类别?

【问题讨论】:

    标签: python pandas matplotlib


    【解决方案1】:

    使用plt.barh,您可以指示所有开始位置,使用 10 分钟作为条形的宽度。用颜色“无”为不需要的位置着色:

    import pandas as pd
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    import numpy as np
    
    dates = pd.date_range(start='2020-02-14 20:30', end='2020-02-24', freq='10min')
    data = pd.DataFrame({'Timestamp': dates,
                         'Validity': (np.round(np.random.uniform(0, .02, len(dates)).cumsum()) % 2).astype(bool)})
    color = 'dodgerblue'
    plt.barh(y=1, left=data['Timestamp'], width=1/24/6, height=0.3,
             color=['none' if not val else color for val in data['Validity']])
    plt.axhline(1, color=color)
    plt.barh(y=0, left=data['Timestamp'], width=1/24/6, height=0.3, color=['none' if val else color for val in data['Validity']])
    plt.axhline(0, color=color)
    
    plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator())
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b'))
    plt.yticks([0, 1], ['False', 'True'])
    # plt.xticks(rotation=30)
    plt.margins(y=0.4)
    plt.ylabel('Validity')
    plt.xlabel('Timestamp')
    plt.tight_layout()
    plt.show()
    

    这是一个稍微复杂的方法,它允许不规则的时间戳。

    首先将布尔列转换为整数(0 用于false1 用于true)。然后计算连续条目之间的差异。这显示了零,而值保持不变,-1,其中False 翻转为True+1 翻转回False。发生这种情况的索引可用于索引时间戳。为了避免第一个和最后一个索引出现问题,需要在数组的开始端附加一个虚拟值。

    import pandas as pd
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    import numpy as np
    
    
    dates = pd.date_range(start='2020-02-14 20:30', end='2020-02-24', freq='10min')
    data = pd.DataFrame({'Timestamp': dates,
                         'Validity': (np.round((np.random.uniform(0, .02, len(dates))).cumsum()) % 2).astype(bool)})
    
    tm = data['Timestamp'].to_numpy()
    tm = np.append(tm, tm[-1])
    
    color = 'navy'
    steps_true = np.diff(np.concatenate([[False], data['Validity'], [False]]).astype(int))
    plt.barh(y=1, left=tm[np.flatnonzero(steps_true == 1)], height=0.2,
             width=tm[np.flatnonzero(steps_true == -1)] - tm[np.flatnonzero(steps_true == 1)], color=color)
    plt.axhline(1, color=color)
    steps_false = np.diff(np.concatenate([[True], data['Validity'], [True]]).astype(int))
    plt.barh(y=0, left=tm[np.flatnonzero(steps_false == -1)], height=0.2,
             width=tm[np.flatnonzero(steps_false == 1)] - tm[np.flatnonzero(steps_false == -1)], color=color)
    plt.axhline(0, color=color)
    
    plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator())
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b'))
    plt.yticks([0, 1], ['False', 'True'])
    plt.margins(y=0.4)
    plt.ylabel('Validity')
    plt.xlabel('Timestamp')
    plt.tight_layout()
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-19
      • 2015-02-11
      • 2020-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2017-09-30
      相关资源
      最近更新 更多