如何在pandas的df.plot.barh水平堆叠条形图中高亮最大数值条
解决方案
你可以在生成条形图之后遍历每一个条形块对象,判断其数值是否为全局最大占比,仅保留最大值条形的原有配色,其余全部改为灰色即可,修改后的完整代码如下:
import matplotlib.pyplot as mpl import matplotlib.cm as mcm import pandas as pd import numpy as np from typing import List, Tuple def read_to_df(file_path: str) -> pd.DataFrame: return pd.read_excel(file_path, index_col = 0) def color_to_hex(color: Tuple[float]) -> str: color = [i * 255 if i * 255 <= 255 else i * 255 - 1 for i in color[:-1]] color = [int(round(i)) for i in color] return "#%02x%02x%02x" % tuple(color) def cmap_to_colors(cmap: str, amount: int) -> List[str]: cmap = mcm.get_cmap(cmap) colors = [color_to_hex(cmap(i)) for i in np.linspace(0, 1, amount)] return colors def main() -> None: df = read_to_df("age_dist_median_six.xlsx") df_age_only = df.drop(["median", "youngest", "oldest"], axis = 1) # 翻转 dataframe 行顺序匹配绘图顺序 df_age_only = df_age_only.iloc[::-1] # 生成原配色方案 colors = cmap_to_colors("viridis", 6) barh = df_age_only.plot.barh(stacked = True, color = colors, width = 0.95, xticks = np.linspace(0, 100, 11), figsize = (10, 15)) # -----------------新增高亮逻辑开始----------------- # 计算所有年龄占比的全局最大值 max_ratio = df_age_only.max().max() # 按patch排列顺序展开所有数值(pandas堆叠条形的patch按列优先排列) all_ratios = df_age_only.values.T.flatten() # 遍历修改颜色 for patch, ratio in zip(barh.patches, all_ratios): if ratio != max_ratio: # 非最大值条形统一设为灰色 patch.set_facecolor('#999999') # -----------------新增高亮逻辑结束----------------- barh.legend(bbox_to_anchor=(1, 1)) barh.margins(x = 0) mpl.savefig("stacked_six_viridis_highlight.png") if __name__ == "__main__": main()
如果你需要按每支队伍内部的最大占比单独高亮,只需要把全局最大值的计算逻辑替换为按行取最大值即可。
内容的提问来源于stack exchange,提问作者Gleb Ryabov
相关产品推荐
相关产品推荐

