如何使用Plotly-Python绘制水平堆叠条形图并将模型名称设为图例
问题分析
你当前的代码是按指标循环创建条形图轨迹(trace),每个轨迹对应一个指标下所有模型的数值,这就导致图例显示的是指标名称而非模型名称。同时,这种堆叠方式会把同一指标下所有模型的分数累加,对于0-1范围的评估指标来说,堆叠后的总和没有实际业务意义——因为每个指标都是独立的模型性能分数,不是构成整体的比例。
解决方案
我们需要调整代码逻辑:遍历模型来创建每个轨迹,这样图例就会显示模型名称;同时根据你的需求,提供两种实现方式:
方式1:水平堆叠条形图(按需求实现)
如果坚持需要堆叠效果,以下代码会将每个指标位置上的所有模型分数堆叠展示:
import plotly.graph_objects as go import pandas as pd from plotly.colors import qualitative # 加载你的模型评估数据 data = [ [0, "LogisticRegression", 0.815068, 0.777778, 0.856115, 0.739130, 0.678058, 0.752876], [1, "K-NearestNeighbors", 0.828767, 0.790850, 0.870504, 0.758454, 0.699958, 0.714476], [2, "SVM", 0.852459, 0.783133, 0.935252, 0.782609, 0.702920, 0.665067], [3, "GaussianProcess", 0.825503, 0.773585, 0.884892, 0.748792, 0.677740, 0.665067], [4, "MLP", 0.774436, 0.811024, 0.741007, 0.710145, 0.694033, 0.735327], [5, "DecisionTree", 0.747170, 0.785714, 0.712230, 0.676329, 0.657586, 0.692216], [6, "ExtraTrees", 0.859060, 0.805031, 0.920863, 0.797101, 0.732490, 0.792698], [7, "RandomForest", 0.826667, 0.770186, 0.892086, 0.748792, 0.673984, 0.778324], [8, "XGBoost", 0.838488, 0.802632, 0.877698, 0.772947, 0.718261, 0.764025], [9, "AdaBoostClassifier", 0.800000, 0.780822, 0.820144, 0.724638, 0.674778, 0.728927], [10, "GBClassifier", 0.835017, 0.784810, 0.892086, 0.763285, 0.696043, 0.754451], [11, "CatBoost", 0.843854, 0.783951, 0.913669, 0.772947, 0.699482, 0.768787], [12, "Stacking", 0.833333, 0.776398, 0.899281, 0.758454, 0.684934, 0.787949], [13, "Voting", 0.836120, 0.781250, 0.899281, 0.763285, 0.692287, 0.778337], [14, "Bagging", 0.855263, 0.787879, 0.935252, 0.787440, 0.710273, 0.792673] ] df = pd.DataFrame(data, columns=["序号", "模型名称", "F1_Score", "Precision", "Recall", "Accuracy", "ROC_AUC", "CV_Score"]) # 准备颜色:使用Plotly内置的定性颜色序列,补充到15种(对应15个模型) mark_colors = qualitative.D3 + qualitative.Alphabet[:5] line_colors = [color.replace('0.8', '1.0') if '0.8' in color else color for color in mark_colors] # 定义指标列表(作为y轴标签) y_labels = ["F1_Score", "Precision", "Recall", "Accuracy", "ROC_AUC", "CV_Score"] fig = go.Figure() # 遍历每个模型,创建对应的轨迹 for idx, model_name in enumerate(df["模型名称"]): # 获取当前模型的所有指标值 metric_values = df.loc[idx, y_labels].tolist() fig.add_trace(go.Bar( y=y_labels, x=metric_values, name=model_name, orientation='h', marker=dict( color=mark_colors[idx], line=dict(color=line_colors[idx], width=1) ) )) # 更新布局:设置堆叠模式、标题、轴标签和图例位置 fig.update_layout( barmode='stack', title="模型评估指标水平堆叠条形图", xaxis_title="指标值总和", yaxis_title="指标名称", legend_title="模型名称", # 将图例放在底部,避免遮挡图表 legend=dict(orientation="h", yanchor="bottom", y=-0.4, xanchor="center", x=0.5) ) fig.show()
方式2:水平分组条形图(更推荐)
对于模型评估指标的对比,分组条形图比堆叠更直观,因为它可以清晰展示每个指标下不同模型的性能差异:
只需要将上述代码中的barmode='stack'改为barmode='group'即可,同时调整x轴标题为"指标值":
fig.update_layout( barmode='group', # 修改为分组模式 title="模型评估指标水平分组条形图", xaxis_title="指标值", yaxis_title="指标名称", legend_title="模型名称", legend=dict(orientation="h", yanchor="bottom", y=-0.4, xanchor="center", x=0.5) )
关键修改点
- 遍历对象变更:从遍历指标改为遍历模型,每个轨迹对应一个模型,这样图例就会显示模型名称。
- 颜色适配:因为有15个模型,所以扩展了颜色序列,确保每个模型有唯一的颜色标识。
- 布局优化:调整图例位置到图表底部,避免遮挡条形图。
内容的提问来源于stack exchange,提问作者Ailurophile
相关产品推荐
相关产品推荐

