如何创建分类进度条
How to create a categorized progress bar
我正在尝试创建一个状态栏,该状态栏与我们目前在其他报告工具中看到的类似(见附图)。我想使用 matplotlib 将其生成为图像,这样它就可以在多个不同的地方和报告中使用。
我找不到一个很好的指南来指导我如何使用 Matplotlib 来做到这一点。我将数据传递为:
results = {'pass': 5, 'fail':18, 'na': 10, 'todo': 187, 'blocked': 12, 'aborted': 10}
我希望它看起来类似于此图表:
谁能指导我找到合适的资源?
我获取了 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
行替换为(你必须用 from matplotlib import transforms
导入 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))
)
- space 文本之间 (
position + 2
)
- 文字大小(
size = 15
)
根据您的需要。
我正在尝试创建一个状态栏,该状态栏与我们目前在其他报告工具中看到的类似(见附图)。我想使用 matplotlib 将其生成为图像,这样它就可以在多个不同的地方和报告中使用。
我找不到一个很好的指南来指导我如何使用 Matplotlib 来做到这一点。我将数据传递为:
results = {'pass': 5, 'fail':18, 'na': 10, 'todo': 187, 'blocked': 12, 'aborted': 10}
我希望它看起来类似于此图表:
谁能指导我找到合适的资源?
我获取了 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
行替换为(你必须用 from matplotlib import transforms
导入 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))
) - space 文本之间 (
position + 2
) - 文字大小(
size = 15
)
根据您的需要。