У меня есть столбиковая диаграмма:
, и это код, который я использую для его создания:
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
Я действительно не уверен, как go об этом, поскольку, насколько я могу судить, данные извлекаются из объекта Axes
, однако он содержит нормализованные значения.
Edit
Я был может в некоторой степени выполнить sh все модификации с помощью этого кода:
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')
Однако это несколько жестко запрограммировано и работает только в том случае, если значения гистограммы нормализованы, что, скорее всего, будет, но не обязательно, поэтому я хотел бы универсальное решение c и не зависит от нормированных значений.