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

如何在R的Plotly子图中为各子图添加额外轨迹?轨迹均集中于顶部

Plotly子图堆叠时次坐标轴错位与子图图例添加解决方案

问题分析

  1. 次坐标轴错位:所有子图的水质参数轨迹和次坐标轴集中在顶部子图,原因是每个子图默认使用相同的次坐标轴ID(y2),Plotly会将所有绑定到y2的轨迹统一渲染到第一个子图的右侧轴。
  2. 子图图例缺失:默认图例为全局共享,未实现每个子图独立显示对应轨迹的图例。

修正代码

time <- c(1:7)
flow <- c(10,9,8,6,6,7,8.5)
NO3 <- c(5,6,6,5,4,3,4)
NH4 <- c(0.2,0.3,0.4,0.6,1,0.9,0.8)
TSS <- c(50,45,40,43,42,41,40)
data <- as.data.frame(cbind(time,flow,NO3,NH4,TSS))

# 带子图索引的绘图函数,实现唯一轴ID与独立图例
Special_plot <- function(data, parameter, rangeQ, ConcRange, idx){ 
    # 生成当前子图的次坐标轴ID和主坐标轴名称
    y_axis_id <- paste0("y", 2 * idx)
    main_y_axis <- if(idx == 1) "y" else paste0("y", 2*idx -1)
    
    fig <- plot_ly(data, x = ~time) %>%
        # 添加流量轨迹,命名唯一避免图例重复
        add_trace(
            type = 'scatter',
            y = ~flow,
            name = paste0("Flow (", parameter, ")"),
            mode = 'lines',
            line = list(color = "#1f77b4"),
            showlegend = TRUE
        ) %>%
        # 添加水质参数轨迹,绑定到当前子图的唯一次坐标轴
        add_trace(
            type = 'scatter',
            y = ~data[,parameter],
            name = parameter,
            mode = 'lines',
            yaxis = y_axis_id,
            showlegend = TRUE
        ) %>%
        layout(
            # 配置当前子图的主Y轴
            yaxis = if(idx ==1) list(title = 'Flow rate', range = rangeQ) else NULL,
            yaxis3 = if(idx ==2) list(title = 'Flow rate', range = rangeQ) else NULL,
            yaxis5 = if(idx ==3) list(title = 'Flow rate', range = rangeQ) else NULL,
            # 配置当前子图的次Y轴,叠加到对应主Y轴
            yaxis2 = if(idx ==1) list(
                title = 'Concentration', 
                range = ConcRange, 
                overlaying = main_y_axis, 
                side = 'right', 
                automargin = TRUE
            ) else NULL,
            yaxis4 = if(idx ==2) list(
                title = 'Concentration', 
                range = ConcRange, 
                overlaying = main_y_axis, 
                side = 'right', 
                automargin = TRUE
            ) else NULL,
            yaxis6 = if(idx ==3) list(
                title = 'Concentration', 
                range = ConcRange, 
                overlaying = main_y_axis, 
                side = 'right', 
                automargin = TRUE
            ) else NULL,
            # 为每个子图设置独立图例位置
            legend = list(x = 1.1, y = 1 - (idx-1)*0.33)
        )
    
    return(fig)
}

rangeQ = c(2,12)

# 创建子图时传入索引,确保轴ID唯一
fig1 <- Special_plot(data, "NO3", rangeQ, c(2,7), idx = 1) 
fig2 <- Special_plot(data, "NH4", rangeQ, c(0,1.5), idx = 2)  
fig3 <- Special_plot(data, "TSS", rangeQ, c(0,50), idx = 3) 

# 组合子图,共享X轴并调整边距
fig <- subplot(fig1, fig2, fig3, nrows = 3, shareX = TRUE, margin = 0.1)
fig

关键修改说明

  • 唯一轴ID:通过idx参数为每个子图生成专属的次坐标轴ID(y2/y4/y6),并绑定到对应子图的主Y轴(y/y3/y5),确保轨迹和坐标轴匹配正确的子图。
  • 独立图例:为每个子图的流量轨迹设置唯一名称,避免图例重复;通过调整legend的Y坐标,让每个图例对应显示在其子图的右侧区域。
  • 轴配置:分别为每个子图配置主、次坐标轴的标题和范围,确保坐标轴显示正确。

内容的提问来源于stack exchange,提问作者François Birgand

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:27:06