共享X轴多Plot分组错乱:Plotly如何实现正确分组?
解决Plotly子图合并后图例分组错乱的问题
问题描述
我有两组指标图表,单独绘制时分组显示正常,但通过subplot共享X轴合并到同一图表后,图例分组出现错乱。第一组(v_plot_sec1)包含K线(candlestick)、ema_8、布林带(bbands);第二组(v_plot_sec2)包含MACD、MACD_signal、RSI、VOLUME,合并后的v_plot_fnl中分组混乱,如何实现正确的分组?
解决方案
Plotly默认不会自动为子图的trace划分图例分组,需手动给每个子图内的所有trace指定相同的legendgroup参数,补全缺失的trace名称,再通过布局优化图例的分组交互:
- 给第一组所有trace设置统一的
legendgroup(如"主图指标"),确保每个trace的name准确对应指标 - 给第二组所有trace设置另一组统一的
legendgroup(如"副图指标"),补全RSI、成交量等trace的name - 合并子图后,通过
layout配置图例的分组折叠功能,支持点击单个指标、双击切换整组显示
修正后的完整代码
library(quantmod) library(dplyr) library(purrr) library(plotly) library(data.table) # 补充加载依赖包,避免报错 get_data <- function(symbols = c("AAPL", "MSFT", "META", "ORCL", "TSLA", "GOOG")) { syms <- getSymbols(symbols, from = "2020/01/01", to = Sys.Date(), periodicity = "daily") map_dfr(syms, function(sym) { raw_data <- get(sym) raw_data %>% as_tibble() %>% set_names(c("OPEN", "HIGH", "LOW", "CLOSE", "VOLUME", "ADJUSTED")) %>% mutate(SYMBOL = sym, DATE = index(raw_data)) %>% select(SYMBOL, DATE, OPEN, HIGH, LOW, CLOSE, VOLUME, ADJUSTED) }) } if (!exists("df_all")) { df_all <- get_data() } p_from_date = Sys.Date() -180 p_to_date = Sys.Date() p_isin = 'AAPL' dt_tst <- as.data.table(df_all[df_all$SYMBOL == 'AAPL',]) dt_tst$inc_dec <- sign(dt_tst$CLOSE-dt_tst$OPEN) dt_tst[dt_tst$inc_dec ==0, ]$inc_dec = 1 dt_tst$Color = '' dt_tst[inc_dec==1,]$Color = '#2F6346'# '#00ff00' dt_tst[inc_dec== -1,]$Color = '#FF4136' #'#ff0000' # t line data dt_tmp_ema8 <- as.data.table(EMA(dt_tst[,CLOSE], n = 8)) names(dt_tmp_ema8) <- 'ema_8' dt_tst <- cbind(dt_tst, dt_tmp_ema8) # #--Processing BBANDS dt_tmp_bbands <- as.data.table(BBands(dt_tst[,CLOSE])) names(dt_tmp_bbands) <- paste0('bbands_',names(dt_tmp_bbands)) dt_tst <- cbind(dt_tst,dt_tmp_bbands) #----On Balance Volume dt_tmp_obv <- as.data.table(OBV(dt_tst[,CLOSE], dt_tst[,VOLUME])) names(dt_tmp_obv) <- 'obv' dt_tst <- cbind(dt_tst,dt_tmp_obv) #----StochWPR dt_tmp_wpr <- as.data.table(sprintf(WPR(dt_tst[,c(HIGH,LOW,CLOSE)]),fmt = '%#.3f')) #---- Average Directional Index dt_tmp_adx <- as.data.table(ADX(dt_tst[,.(HIGH,LOW,CLOSE)])) dt_tst <- cbind(dt_tst,dt_tmp_adx) #-----RSI dt_tmp_RSI <- as.data.table(RSI(dt_tst[,.(CLOSE)])) names(dt_tmp_RSI) = 'RSI' dt_tst <- cbind(dt_tst,dt_tmp_RSI) #---- MACD dt_tmp_macd <- as.data.table(MACD(dt_tst[,.(CLOSE)], 12, 26,9,maType = 'EMA')) names(dt_tmp_macd) <- c('macd','macd_signal') dt_tst <- cbind(dt_tst,dt_tmp_macd) #-- Graphing-------------------------------------------------------------------- # Section 1:主图指标(K线、EMA、布林带) cndlstick <- plot_ly(name = 'K线' ,data = dt_tst,type='candlestick', x = ~DATE, low=~LOW, high = ~HIGH, open = ~OPEN, close=~CLOSE, legendgroup = "主图指标") v_plot_sec1 <- add_trace(cndlstick, name = 'ema_8', data = dt_tst, type = 'scatter', mode = 'lines', x= ~DATE, y = ~ema_8, line = list(color = 'black', width = 2), legendgroup = "主图指标") v_plot_sec1 <- add_trace(v_plot_sec1, name = '布林带下轨', data = dt_tst, type = 'scatter', mode = 'lines', x= ~DATE, y = ~bbands_dn, line = list(color = 'gray', width = 1), legendgroup = "主图指标") v_plot_sec1 <- add_trace(v_plot_sec1, name = '布林带中轨', data = dt_tst, type = 'scatter', mode = 'lines', x= ~DATE, y = ~bbands_mavg, line = list(color = 'black', width = 1,linetype =I("dash") ), legendgroup = "主图指标") v_plot_sec1 <- add_trace(v_plot_sec1, name = '布林带上轨', data = dt_tst, type = 'scatter', mode = 'lines', x= ~DATE, y = ~bbands_up, line = list(color = 'gray', width = 1), legendgroup = "主图指标") # Section 2:副图指标(MACD、RSI、成交量) v_plot_sec2 <- plot_ly(name = 'MACD', data = dt_tst, type = 'scatter', mode = 'lines', x=~DATE,y=~macd,line = list(color = 'black', width = 1), legendgroup = "副图指标") v_plot_sec2 <- add_trace(v_plot_sec2, name = 'MACD信号线', data = dt_tst, type = 'scatter', mode = 'lines', x=~DATE,y=~macd_signal,line = list(color = 'red', width = 1), legendgroup = "副图指标") y2 <- list(tickfont = list(color = "#ff7f0e"),titlefont = list(color = "#ff7f0e"),overlaying = "y",side = "left", anchor="free", position=0.15, title = "RSI") v_plot_sec2 <- v_plot_sec2 %>% add_trace(name = 'RSI', type = 'scatter', mode = 'lines', x=~dt_tst$DATE,y=~dt_tst$RSI, yaxis = "y2", line = list(color = 'black', width = 1), legendgroup = "副图指标") y3 <- list(tickfont = list(color = "#d62728"),titlefont = list(color = "#d62728"),overlaying = "y",side = "right",title = "成交量") v_plot_sec2 <- v_plot_sec2%>% add_trace(name = '成交量', data = dt_tst, type = 'bar', x=~DATE, y=~VOLUME, yaxis = "y3",marker = list(color = ~toRGB(Color, alpha = 0.5)), legendgroup = "副图指标") # 调整副图布局,优化轴标题 v_plot_sec2 <- v_plot_sec2 %>% layout(yaxis2 = y2, yaxis3 = y3, xaxis = list(title = '日期'), yaxis = list(title="MACD", tickfont = list(color = "#1f77b4"),titlefont = list(color = "#1f77b4")) )%>% layout(plot_bgcolor='#e5ecf6',xaxis = list(zerolinecolor = '#ffff',zerolinewidth = 2,gridcolor = 'ffff'),yaxis = list(zerolinecolor = '#ffff',zerolinewidth = 2,gridcolor = 'ffff')) # 合并子图并配置图例分组交互 v_plot_fnl <- subplot(v_plot_sec1,v_plot_sec2,heights = c(0.6,0.3), nrows= 2, shareX = TRUE, titleY = TRUE) %>% layout( title = "AAPL 技术指标组合图", legend = list( tracegroupgap = 20, # 分组之间的间距 itemclick = "toggleitem", # 点击切换单个指标显示 itemdoubleclick = "togglegroup" # 双击切换整组指标显示 ) ) # 查看最终图表 v_plot_fnl
内容的提问来源于stack exchange,提问作者VSR
相关产品推荐
相关产品推荐

