如何在Python Plotly子图中合并图例项为单个图例?
解决Plotly双Scattermapbox子图合并图例的问题
要实现两个子图的图例合并,核心是利用**legendgroup**将相同分类的trace归为一组,并控制每组仅显示一次图例条目。具体修改如下:
修改后的完整代码
import pandas as pd import numpy as np import plotly.graph_objects as go from plotly.subplots import make_subplots import plotly.express as px df = pd.DataFrame({'Type' : ['1','1','1','1','1','2','2','2','2','2'], 'Category' : ['A','D','D','D','F','B','D','A','D','E'] }) df['Color'] = df['Category'].map(dict(zip(df['Category'].unique(), px.colors.qualitative.Dark24[:len(df['Category'].unique())]))) df = pd.concat([df]*10, ignore_index = True) df['Lat'] = np.random.randint(0, 20, 100) df['Lon'] = np.random.randint(0, 20, 100) Color = df['Color'].unique() Category = df['Category'].unique() cats = dict(zip(Color, Category)) df_type_1 = df[df['Type'] == '1'].copy() df_type_2 = df[df['Type'] == '2'].copy() fig = make_subplots( rows = 1, cols = 2, specs = [[{"type": "scattermapbox"}, {"type": "scattermapbox"}]], vertical_spacing = 0.05, horizontal_spacing = 0.05 ) # 记录已添加到图例的分类 added_legends = set() # 添加第一个子图的trace for c in df_type_1['Color'].unique(): df_color = df_type_1[df_type_1['Color'] == c] cat = cats[c] fig.add_trace(go.Scattermapbox( lat = df_color['Lat'], lon = df_color['Lon'], mode = 'markers', name = cat, marker = dict(color = c), opacity = 0.8, legendgroup = cat, # 同分类归为同一图例组 showlegend = True # 首次添加时显示图例 ), row = 1, col = 1 ) added_legends.add(cat) # 添加第二个子图的trace for c in df_type_2['Color'].unique(): df_color = df_type_2[df_type_2['Color'] == c] cat = cats[c] fig.add_trace(go.Scattermapbox( lat = df_color['Lat'], lon = df_color['Lon'], mode = 'markers', name = cat, marker = dict(color = c), opacity = 0.8, legendgroup = cat, # 与对应分类的图例组关联 # 仅当分类未在图例中出现时才显示 showlegend = False if cat in added_legends else True ), row = 1, col = 2 ) if cat not in added_legends: added_legends.add(cat) fig.update_layout(height = 600, width = 800, margin = dict(l = 10, r = 10, t = 30, b = 10)); fig.update_layout(mapbox1 = dict(zoom = 2, style = 'carto-positron'), mapbox2 = dict(zoom = 2, style = 'carto-positron'), ) fig.show()
关键修改说明
legendgroup分组:将所有属于同一Category的trace设置为同一个legendgroup,确保点击图例时,两个子图中对应分类的标记会同步显示/隐藏。- 控制图例显示:用集合
added_legends记录已经添加过图例的分类,仅让每个分类的第一个trace显示图例,后续同分类的trace(无论在哪个子图)都隐藏图例,避免重复条目。 - 保留独有分类图例:对于第二个子图中独有的分类(如B、E),因为未在
added_legends中,会自动显示其图例条目,不会丢失。
内容的提问来源于stack exchange,提问作者jonboy
相关产品推荐
相关产品推荐

