簡體   English   中英

不連續單杠 plot

[英]Discontinuous horizontal bar plot

考慮以下數據框

                 A      B
2022-09-28     1.3    0.0
2022-09-29     1.3    0.0
2022-09-30     1.3    0.9
2022-10-01     1.3    0.9
2022-10-02     0.0    0.9
2022-10-03     0.0    0.9
2022-10-04     0.0    0.0
2022-10-05     0.1    0.0
2022-10-06     0.1    0.0
2022-10-07     0.1    0.0

我需要一個水平條 plot,它具有兩個垂直水平(A 和 B)和 x 軸上的日期。 條形的長度(條寬)等於非零值的時間間隔,線寬(條形高度)等於值的平均值。

例如,我們將在 A 級別設置兩個欄。 第一個從 2022-09-28 到 2022-10-01,線寬 1.3,第二個從 2022-10-05 到 2022-10-07,線寬 0.1。 在 B 級別上,只有從 2022-09-30 到 2022-10-03 的一根柱線,線寬為 0.9。

非常接近,但它是每個級別僅一個條的解決方案。

您可以使用 Matplotlib 的broken_barh function 到 plot 各種不連續(“破碎”)水平條形圖。 訣竅是將 dataframe 中的數據正確地提供給broken_barh :您需要為不連續柱 plot 的每個部分創建(x start, x duration)

例如,A 有您提到的兩個部分。 一部分是(2022-09-28, 3 days) ,線寬為 1.3,第二部分是(2022-10-05, 2 days) ,線寬為 0.1。 我們將為broken_barh提供 x 范圍[(2022-09-28, 3 days), (2022-10-05, 2 days)]和線寬[1.3, 0.1]

import matplotlib.pyplot as plt
import pandas as pd


if __name__ == '__main__':

    # Create dataframe    
    df_dates = pd.date_range('2022-09-28', periods=10)
    df = pd.DataFrame({'A': [1.3, 1.3, 1.3, 1.3, 0.0, 0.0, 0.0, 0.1, 0.1, 0.1],
                       'B': [0.0, 0.0, 0.9, 0.9, 0.9, 0.9, 0.0, 0.0, 0.0, 0.0]},
                      index=df_dates)

    # xranges and linewidth we will feed matplotlib later
    a_xranges = []
    a_lw = []

    # Find unique values in A - aka the parts of the A broken bar plot
    for lw_value in df['A'].unique().tolist():
        if lw_value != 0.0:  # skip 0.0, we will not plot it
            
            # Find rows where linewidth for the A values is located
            idx = df.index[df['A'] == lw_value].tolist()
            sub_df = df.loc[idx]

            # Find where the bar plot starts for x axis and x duration
            x_range = (sub_df.index[0], sub_df.index[-1] - sub_df.index[0])  # (x start, x duration)

            # Add x range and linewidth values for that part
            a_xranges.append(x_range)
            a_lw.append(lw_value)

a_xrangesa_lwbroken_barh的正確格式。 Matplotlib 將管理 pandas 日期,因此您不必擔心日期格式。

您可以對 B 重復相同的操作 - 您也可以制作一個 function 並調用它,而不是添加相同的循環來清理您的代碼。

    b_xranges = []
    b_lw = []

    for lw_value in df['B'].unique().tolist():
        if lw_value != 0.0:
            idx = df.index[df['B'] == lw_value].tolist()
            sub_df = df.loc[idx]
            x_range = (sub_df.index[0], sub_df.index[-1] - sub_df.index[0])   
            b_xranges.append(x_range)
            b_lw.append(lw_value)

    # Start figure
    fig, ax = plt.subplots(figsize=(12, 5))
    # Plot A bar plot
    # The (10,9) is for the y axis (ymin, y duration)
    ax.broken_barh(a_xranges, (10, 9), edgecolor='k', facecolor='white', linewidth=a_lw)
    # Plot B bar plot
    ax.broken_barh(b_xranges, (20, 9), edgecolor='k', facecolor='white', linewidth=b_lw)

    ax.set_ylabel("Level")
    ax.set_yticks([15, 25], labels=['A', 'B'])
    ax.set_xlabel("Date")
    plt.show()

示例圖片

如果你想讓條形更近、更窄等……你可以使用我給它們的 y 值(10,9)(20,9)值。 希望這會有所幫助 - 干杯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM