You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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()

关键修改说明

  1. legendgroup 分组:将所有属于同一Category的trace设置为同一个legendgroup,确保点击图例时,两个子图中对应分类的标记会同步显示/隐藏。
  2. 控制图例显示:用集合added_legends记录已经添加过图例的分类,仅让每个分类的第一个trace显示图例,后续同分类的trace(无论在哪个子图)都隐藏图例,避免重复条目。
  3. 保留独有分类图例:对于第二个子图中独有的分类(如B、E),因为未在added_legends中,会自动显示其图例条目,不会丢失。

内容的提问来源于stack exchange,提问作者jonboy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:15:38