【问题标题】:How to create a categorized progress bar如何创建分类进度条
【发布时间】:2021-10-15 10:14:15
【问题描述】:

我正在尝试创建一个类似于我们目前在不同报告工具中看到的状态栏(见附图)。我想使用 matplotlib 将其生成为图像,这样它就可以在多个不同的地方和报告中使用。

我找不到一个很好的指南来指导我如何使用 Matplotlib 来做到这一点。我将数据传递为:

results = {'pass': 5, 'fail':18, 'na': 10, 'todo': 187, 'blocked': 12, 'aborted': 10}

我希望它看起来类似于此图表:

谁能指导我找到正确的资源?

【问题讨论】:

    标签: python matplotlib plot data-visualization visualization


    【解决方案1】:

    我采用了documentation 的代码并应用了一些更改,以便将其应用于您的案例。

    import matplotlib.pyplot as plt
    import numpy as np
    
    results = {'Pass': 5, 'Fail':18, 'Na': 10, 'Todo': 187, 'Blocked': 12, 'Aborted': 10}
    
    category_names = [f'{value} {category.upper()}' for category, value in results.items()]
    
    results = {'1': list(results.values())}
    
    labels = list(results.keys())
    data = np.array(list(results.values()))
    data_cum = data.cumsum(axis = 1)
    category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15, 0.85, data.shape[1]))
    
    fig = plt.figure(figsize = (10, 2))
    ax = fig.add_axes([0.1, 0.4, 0.8, 0.4])
    
    ax.axis('off')
    
    for i, (colname, color) in enumerate(zip(category_names, category_colors)):
        widths = data[:, i]
        starts = data_cum[:, i] - widths
        ax.barh(labels, widths, left = starts, height = 0.5, label = colname, color = color)
    
    ax.legend(ncol = len(category_names), bbox_to_anchor = (0, 0), loc = 'upper left', fontsize = 10, frameon = False)
    
    plt.show()
    

    如果您也想格式化图例,可以将上面的ax.legend 行替换为(您必须将transforms 导入为from matplotlib import transforms):

    handles, labels = ax.get_legend_handles_labels()
    
    for label, color, position in zip(labels, category_colors, np.linspace(0, 220, len(labels))):
        text = plt.text(position, -0.5, label.split()[0] + ' ', color = color, size = 15, horizontalalignment = 'right')
        text.draw(fig.canvas.get_renderer())
        ex = text.get_window_extent()
        transforms.offset_copy(text._transform, y = ex.height, units = 'dots')
        text = plt.text(position + 2, -0.5, label.split()[1], color = 'black', size = 10, horizontalalignment = 'left')
        text.draw(fig.canvas.get_renderer())
        ex = text.get_window_extent()
        transforms.offset_copy(text._transform, y = ex.height, units = 'dots')
    

    在这种情况下你必须优化:

    • 图形大小 (figsize = (10, 2))
    • 图例总长度 (np.linspace(0, 220, len(labels)))
    • 文本之间的空格 (position + 2)
    • 文字大小 (size = 15)

    根据您的需要。

    【讨论】:

    • 感谢您对此的帮助!效果很好!我唯一要弄清楚的是如何指定标签颜色。 :)
    • 在上面的例子中,颜色是从category_colors 中挑选出来的,它从颜色图plt.get_cmap('RdYlGn') 中获取颜色
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-27
    • 2019-03-11
    • 2018-03-08
    • 2015-04-05
    • 2019-03-12
    • 1970-01-01
    相关资源
    最近更新 更多