如何在Python的Seaborn Pointplot中分组连接点并添加分类颜色
Python复刻R图表:实现分组点连接与指定分类颜色
我正在用Python开展项目,在Kaggle上看到一幅用R绘制的精美图表,但我不熟悉R语言。测试数据采用Kaggle的【Monthly Electricity Production in GWh [2010-2022]】,目前已用Python的Seaborn库复刻出接近的图表,现有代码如下:
grid = sns.FacetGrid(data=breakdown, col="country", col_wrap=7, height=3, aspect=1, sharex=True, sharey=False) grid.map_dataframe(sns.pointplot, x="value", y="product", hue="year", join=False, markers=["o", "*"]) grid.set_titles("{col_name}") grid.set_axis_labels("[%]", "") grid.set(xlim=(0, 100), ylim=(-0.5, 2.5)) grid.despine(right=True, top=True) grid.add_legend(loc="upper left", frameon=False)
现在需要实现两个需求:
- 同组(同一国家+同一能源类型)内不同年份的点用线连接
- 为
Nuclear、Renewables、Fossil fuels三个能源分类设置对应固定颜色
所用breakdown数据集样本:
,country,year,product,value 0,Australia,2010,Renewables,10.400785746199682 12,Australia,2022,Renewables,34.742331289873064 467,Australia,2022,Nuclear,0.0 455,Australia,2010,Nuclear,0.0 910,Australia,2010,Fossil fuels,89.59921045031392 922,Australia,2022,Fossil fuels,65.25766871012695 13,Austria,2010,Renewables,67.75576873959946 25,Austria,2022,Renewables,78.76446322617821 480,Austria,2022,Nuclear,0.0 468,Austria,2010,Nuclear,0.0 923,Austria,2010,Fossil fuels,32.24423569765363 935,Austria,2022,Fossil fuels,21.235536776894953 493,Belgium,2022,Nuclear,45.295925696472636 481,Belgium,2010,Nuclear,49.984697658490894 948,Belgium,2022,Fossil fuels,27.7838958679145 38,Belgium,2022,Renewables,26.9201784290824 26,Belgium,2010,Renewables,8.396529615422356 936,Belgium,2010,Fossil fuels,41.61877381915019 494,Canada,2010,Nuclear,14.608937138869305 949,Canada,2010,Fossil fuels,22.769913684560386 961,Canada,2022,Fossil fuels,17.25003004705112 51,Canada,2022,Renewables,69.86121900236432 39,Canada,2010,Renewables,62.62114900575948 506,Canada,2022,Nuclear,12.888750950897817
解决方案
1. 定义能源分类的颜色映射
先创建一个字典,为每个能源类型指定固定颜色,可根据需求调整颜色值:
color_map = { "Nuclear": "#27ae60", # 绿色 "Renewables": "#3498db", # 蓝色 "Fossil fuels": "#e74c3c"# 红色 }
2. 修改Seaborn绘图代码
核心调整点:
- 将
hue参数从year改为product,让同能源类型的点自动连接 - 用
style参数区分不同年份,保留原有的标记样式 - 指定
palette为自定义颜色映射 - 调整图例显示,避免重复项
修改后的完整代码:
# 先对数据排序,确保连线顺序按年份排列 breakdown_sorted = breakdown.sort_values(by=["country", "product", "year"]) grid = sns.FacetGrid(data=breakdown_sorted, col="country", col_wrap=7, height=3, aspect=1, sharex=True, sharey=False) # 使用pointplot实现同能源类型点的连接,用style区分年份 grid.map_dataframe( sns.pointplot, x="value", y="product", hue="product", style="year", join=True, markers=["o", "*"], palette=color_map, dodge=False # 关闭偏移,让同能源类型的点在同一y轴位置对齐 ) grid.set_titles("{col_name}") grid.set_axis_labels("[%]", "") grid.set(xlim=(0, 100), ylim=(-0.5, 2.5)) grid.despine(right=True, top=True) # 调整图例:去重并统一位置 handles, labels = grid.axes[0].get_legend_handles_labels() filtered_handles = [] filtered_labels = [] seen = set() for h, l in zip(handles, labels): if l not in seen: seen.add(l) filtered_handles.append(h) filtered_labels.append(l) grid.fig.legend(filtered_handles, filtered_labels, loc="upper left", frameon=False, bbox_to_anchor=(0.05, 0.95)) # 移除子图默认图例 for ax in grid.axes.flat: ax.legend_.remove()
说明
- 排序数据是为了保证连线按2010到2022的年份顺序,避免连线混乱
dodge=False让同一能源类型的不同年份点在同一y轴位置对齐,连线更直观- 图例去重处理避免了每个子图重复显示图例,让整体布局更整洁
内容的提问来源于stack exchange,提问作者Gabriel Facheti
相关产品推荐
相关产品推荐

