【发布时间】:2020-10-09 12:25:22
【问题描述】:
我有一个这样的条形图:
这是我用来生成它的代码:
def performance_plot_builder(data: str, ax: pyplot.Axes):
df = pandas.read_csv(data, header=0, sep=';')
df[['library', 'function']] = df.name.str.split('_', expand=True, n=1)
df = df.pivot('function', 'library', 'elapsed')
normalized = df.div(df.max(axis=1), axis=0)
normalized.plot(ax=ax, kind='bar', color=[c.value for c in Color])
ax.set_ylabel('execution time (normalized)')
for p in ax.patches:
ax.annotate(str(p.get_height()), (p.get_x() * 1.005, p.get_height() * 1.005))
数据首先相对于每个项目的两个系列之间的最大值进行归一化,然后绘制。我已经能够注释每个条上的值,但是我想要一些修改:
我只希望显示在两个值的最大值上的值。例如,对于
array_access,只会显示stl条的值,因为它大于etl。-
我最需要的是显示非标准化值而不是现在的标准化值(所以
df数据帧而不是normalized数据帧。 我还希望将标签旋转 90 度,以便标签显示在条本身上。
这是我拥有的示例数据框:
library etl stl
function
copy 6.922975e-06 6.319098e-06
copy_if 1.369602e-04 1.423410e-04
count 6.135367e-05 1.179409e-04
count_if 1.332942e-04 1.908408e-04
equal 1.099963e-05 1.102448e-05
fill 5.337406e-05 9.352984e-05
fill_n 6.412923e-05 9.354095e-05
find 4.354274e-08 7.804437e-08
find_if 4.792641e-08 9.206846e-08
iter_swap 4.898631e-08 4.911048e-08
rotate 2.816952e-04 5.219732e-06
swap 2.832723e-04 2.882649e-04
swap_ranges 3.492764e-04 3.576686e-04
transform 9.739075e-05 1.080187e-04
我真的不知道该怎么做,因为据我所知,数据是从 Axes 对象中检索到的,但是它包含标准化值。
编辑
我能够用这段代码完成所有的修改:
interleaved = [val for pair in zip(df['etl'], df['stl']) for val in pair]
for v, p in zip(interleaved, ax.patches):
if p.get_height() == 1:
ax.text(x=p.get_x() + 0.01, y=0.825, s=f'{v:.1E}', rotation=90, color='white')
但是,这有点硬编码,只有在条形图值被规范化时才有效,它们很可能是,但不一定,所以我想要一个通用的解决方案,独立于规范化值。
【问题讨论】:
标签: python pandas matplotlib charts