不同机器运行matplotlib脚本图例颜色不一致问题求助
问题解决:折线图图例颜色匹配错误
问题原因
你当前的代码通过plt.legend()手动指定标签列表,但未明确将每个线条与标签绑定,而是依赖Matplotlib自动收集绘图对象的顺序。不同环境下(比如Seaborn内部逻辑差异、数据加载的细微变化),线条的收集顺序可能和预期不一致,导致图例标签与线条颜色错位。
解决方案
方法一:手动创建图例元素(精准控制对应关系)
先保存所有绘制的线条对象,再手动将线条与标签一一绑定,彻底避免顺序问题:
plt.figure(figsize=(15, 9)) plt.style.use('fivethirtyeight') # 绘制所有折线并保存线条对象 line_national = sns.lineplot(x = pd.to_datetime(buyer_comp_trend['week']).dt.strftime('%m/%d'), y = buyer_comp_trend['Composite Score'], color = '#0000ff', linewidth=7.) line_ce = sns.lineplot(x = pd.to_datetime(buyer_comp_trend_ce['week']).dt.strftime('%m/%d'), y = buyer_comp_trend_ce['Composite Score'], color = '#99ccff', linewidth=3.) line_ea = sns.lineplot(x = pd.to_datetime(buyer_comp_trend_ea['week']).dt.strftime('%m/%d'), y = buyer_comp_trend_ea['Composite Score'], color = '#990099', linewidth=3.) line_ma = sns.lineplot(x = pd.to_datetime(buyer_comp_trend_ma['week']).dt.strftime('%m/%d'), y = buyer_comp_trend_ma['Composite Score'], color = '#1f1f1f', linewidth=3.) line_ms = sns.lineplot(x = pd.to_datetime(buyer_comp_trend_ms['week']).dt.strftime('%m/%d'), y = buyer_comp_trend_ms['Composite Score'], color = '#00b050', linewidth=3.) line_sc = sns.lineplot(x = pd.to_datetime(buyer_comp_trend_sc['week']).dt.strftime('%m/%d'), y = buyer_comp_trend_sc['Composite Score'], color = '#ff66cc', linewidth=3.) line_so = sns.lineplot(x = pd.to_datetime(buyer_comp_trend_so['week']).dt.strftime('%m/%d'), y = buyer_comp_trend_so['Composite Score'], color = '#996633', linewidth=3.) line_we = sns.lineplot(x = pd.to_datetime(buyer_comp_trend_we['week']).dt.strftime('%m/%d'), y = buyer_comp_trend_we['Composite Score'], color = '#ff8205', linewidth=3.) # 绘制目标线并保存线条对象 line_target, = plt.plot(pd.to_datetime(buyer_comp_trend['week']).dt.strftime('%m/%d'), buyer_comp_trend['Target'], c = '#808080', ls = '--') # 设置图表属性 plt.gca().set(title = 'HRX Composite Score (Region scores by week)', ylabel='', xlabel="", facecolor = '#ffffff') plt.ylim(920, 980) # 手动绑定线条与标签 lines = [line_national.lines[0], line_ce.lines[0], line_ea.lines[0], line_ma.lines[0], line_ms.lines[0], line_sc.lines[0], line_so.lines[0], line_we.lines[0], line_target] labels = ['National', 'CE', 'EA', 'MA', 'MS', 'SC', 'SO', 'WE', 'Target (939)'] plt.legend(lines, labels, ncol=9)
方法二:合并数据用Seaborn自动处理图例(更简洁)
把所有区域的数据合并到一个DataFrame,用hue参数指定分组,让Seaborn自动生成匹配的图例,无需手动指定标签:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 为每个数据集添加区域标识列 buyer_comp_trend['Region'] = 'National' buyer_comp_trend_ce['Region'] = 'CE' buyer_comp_trend_ea['Region'] = 'EA' buyer_comp_trend_ma['Region'] = 'MA' buyer_comp_trend_ms['Region'] = 'MS' buyer_comp_trend_sc['Region'] = 'SC' buyer_comp_trend_so['Region'] = 'SO' buyer_comp_trend_we['Region'] = 'WE' # 合并所有数据到一个DataFrame combined_df = pd.concat([buyer_comp_trend, buyer_comp_trend_ce, buyer_comp_trend_ea, buyer_comp_trend_ma, buyer_comp_trend_ms, buyer_comp_trend_sc, buyer_comp_trend_so, buyer_comp_trend_we]) combined_df['week_formatted'] = pd.to_datetime(combined_df['week']).dt.strftime('%m/%d') # 绘图 plt.figure(figsize=(15, 9)) plt.style.use('fivethirtyeight') # 绘制所有区域折线,用hue分组并指定颜色 sns.lineplot(data=combined_df, x='week_formatted', y='Composite Score', hue='Region', linewidth=3, palette={ 'National': '#0000ff', 'CE': '#99ccff', 'EA': '#990099', 'MA': '#1f1f1f', 'MS': '#00b050', 'SC': '#ff66cc', 'SO': '#996633', 'WE': '#ff8205' }) # 单独设置National线条宽度 for line in plt.gca().lines: if line.get_label() == 'National': line.set_linewidth(7) # 绘制目标线 plt.plot(combined_df['week_formatted'].unique(), buyer_comp_trend['Target'], c='#808080', ls='--', label='Target (939)') # 设置图表属性 plt.title('HRX Composite Score (Region scores by week)') plt.ylabel('') plt.xlabel('') plt.gca().set_facecolor('#ffffff') plt.ylim(920, 980) plt.legend(ncol=9)
说明
两种方法都能解决图例颜色错位问题:
- 方法一适合保留原有代码结构,通过手动绑定确保对应关系;
- 方法二更符合Seaborn的使用习惯,代码更简洁,减少手动维护的错误。
内容的提问来源于stack exchange,提问作者Abe
相关产品推荐
相关产品推荐

