如何在Pandas条形图上标注非标准化最大值并优化标签?
解决方案:修改Pandas条形图标注逻辑
这里是针对你需求的完整修改后的代码,完美实现三个要求:
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)') # 预处理:获取每个function对应的最大值信息 max_values = df.max(axis=1) max_libraries = df.idxmax(axis=1) # 获取绘图时的library顺序,对应条形的排列顺序 library_order = df.columns.tolist() # 将条形按每组2个分组(每个function对应一组) patch_groups = [ax.patches[i:i+2] for i in range(0, len(ax.patches), 2)] # 遍历每个function对应的条形组 for (function, max_lib, max_val), patches in zip(zip(max_values.index, max_libraries, max_values), patch_groups): # 找到当前组中对应最大值library的条形 for patch, lib in zip(patches, library_order): if lib == max_lib: # 定位标签到条形内部中心位置 x = patch.get_x() + patch.get_width() / 2 y = patch.get_height() / 2 # 添加标注:原始值、旋转90度、白色字体 ax.text( x=x, y=y, s=f'{max_val:.1E}', rotation=90, color='white', ha='center', va='center' ) break # 找到目标条形后跳出循环,处理下一组
关键修改点解释:
仅标注每组最大值:
先通过df.idxmax(axis=1)获取每个function组中耗时最大的library,再把条形按每两个一组(对应每个function的两个库)分组,遍历每组时精准定位到对应最大值库的条形,只给它添加标注。显示非归一化原始值:
直接从原始的df中提取最大值(df.max(axis=1)),完全避开归一化后的数据,确保标注的是真实的执行时间。标签旋转90度并显示在条形内部:
通过计算条形的中心坐标(x取条形宽度的中点,y取条形高度的中点),把标签固定在条形内部,设置rotation=90旋转文本,同时用ha='center'和va='center'保证文本居中对齐,白色字体让内部标签更清晰易读。
这个方案完全摆脱了硬编码限制,不管你的library数量是2个还是更多(只要每组数量一致)都能正常工作,而且严格对应原始数据,不会受归一化逻辑影响。
内容的提问来源于stack exchange,提问作者Richard Robinson
相关产品推荐
相关产品推荐

