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

如何基于Plotly的subplot实现带独立图例的分面图并正常导出?

解决方案:Plotly Subplot实现带独立子图图例的分面图

要解决用subplot组合图表时保留每个子图独立图例的问题,核心是通过配置每个trace的legendgroup避免图例合并,同时调整布局预留图例空间。以下是R和Python的具体实现:

R 实现示例

library(plotly)
library(dplyr)

# 构造示例数据
set.seed(123)
df <- expand.grid(
  category = c("A", "B", "C"),
  subplot_group = paste0("Subplot ", 1:4)
) %>%
  mutate(value = sample(1:10, nrow(.), replace = TRUE))

# 生成带独立图例的子图列表
subplots_list <- lapply(unique(df$subplot_group), function(group) {
  sub_df <- filter(df, subplot_group == group)
  
  plot_ly(sub_df, x = ~category, y = ~value, type = "bar",
          color = ~category,
          # 为每个子图的trace设置唯一图例组,避免全局合并
          legendgroup = paste0(group, "_", ~category),
          showlegend = TRUE) %>%
    layout(title = group,
           # 加大右侧边距,给图例预留空间
           margin = list(r = 100))
})

# 组合子图并调整全局布局
combined_plot <- subplot(subplots_list, nrows = 2, shareX = TRUE, shareY = TRUE) %>%
  layout(
    margin = list(t = 50, b = 50, l = 50),
    # 关闭全局图例容器,仅保留子图内的独立图例
    showlegend = FALSE
  )

# 查看图表
combined_plot

# 导出PDF(需提前安装orca)
orca(combined_plot, "subplots_individual_legends.pdf")

Python 实现示例

import plotly.express as px
import plotly.subplots as sp
import pandas as pd
import numpy as np

# 构造示例数据
np.random.seed(123)
df = pd.DataFrame({
    "category": np.tile(["A", "B", "C"], 4),
    "subplot_group": np.repeat([f"Subplot {i}" for i in range(1,5)], 3),
    "value": np.random.randint(1, 11, 12)
})

# 生成带独立图例的子图列表
subplots_list = []
for group in df["subplot_group"].unique():
    sub_df = df[df["subplot_group"] == group]
    fig = px.bar(sub_df, x="category", y="value", color="category")
    
    # 为每个trace设置唯一图例组
    for trace in fig.data:
        trace.legendgroup = f"{group}_{trace.name}"
        trace.showlegend = True
    
    # 调整子图边距
    fig.update_layout(margin=dict(r=100), title_text=group)
    subplots_list.append(fig)

# 组合子图
combined_fig = sp.make_subplots(rows=2, cols=2, subplot_titles=[f"Subplot {i}" for i in range(1,5)])

# 将子图的trace添加到组合图中
for idx, fig in enumerate(subplots_list):
    row = (idx // 2) + 1
    col = (idx % 2) + 1
    for trace in fig.data:
        combined_fig.add_trace(trace, row=row, col=col)

# 调整全局布局
combined_fig.update_layout(
    showlegend=False,
    margin=dict(t=50, b=50, l=50)
)

# 显示图表
combined_fig.show()

# 导出PDF(需提前安装orca)
combined_fig.write_image("subplots_individual_legends.pdf")

关键配置说明

  • legendgroup:给每个子图的所有trace分配唯一的组名,确保Plotly不会将不同子图的图例项合并成全局图例。
  • showlegend = TRUE:每个子图的trace都开启图例显示,保证每个子图旁出现独立图例。
  • 边距调整:通过margin参数为每个子图的右侧预留足够空间,避免图例与相邻子图重叠。
  • 全局showlegend = FALSE:关闭全局图例容器,防止出现重复的全局图例项。

注意事项

  • 导出PDF需要依赖Plotly的orca工具,R中可通过plotly::install_orca()安装,Python需单独下载安装orca。
  • 根据图例文字长度调整margin的r值,避免图例被截断或布局混乱。
  • 若子图数量或布局不同,可调整nrows/ncols参数,或使用specs自定义子图布局。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:47:04