【问题标题】:How to apply subplot to a list of plots with secondary y axis如何将子图应用于具有辅助 y 轴的图列表
【发布时间】:2021-01-18 02:51:12
【问题描述】:

我想准备一个子图,其中每个方面都是一个变量与其他变量的单独双 y 轴图。所以我做了一个基础图p 并在循环中添加辅助 y 轴变量:

library(rlang)
library(plotly)
library(tibble)

dual_axis_lines <- function(data, x, y_left, ..., facets = FALSE, axes = NULL){
  x <- rlang::enquo(x)
  y_left <- rlang::enquo(y_left)
  y_right <- rlang::enquos(...)
  
  y_left_axparms <- list(
    title = FALSE,
    tickfont = list(color = "#1f77b4"),
    side = "left")
  y_right_axparms <- list(
    title = FALSE,
    overlaying = "y",
    side = "right",
    zeroline = FALSE)
  
  p <- plotly::plot_ly(data , x = x) %>%
    plotly::add_trace(y = y_left, name = quo_name(y_left),
                      yaxis = "y1", type = 'scatter', mode = 'lines', 
                      line = list(color = "#1f77b4"))
  
  p_facets <- list()
  for(v in y_right){
    p_facets[[quo_name(v)]] <- p %>%
      plotly::add_trace(y = v, name = quo_name(v),
                        yaxis = "y2", type = 'scatter', mode = 'lines') %>%
      plotly::layout(yaxis = y_left_axparms,
                     yaxis2 = y_right_axparms)
  }
  p <- subplot(p_facets, nrows = length(y_right), shareX = TRUE)
  return(p)
}

mtcars %>% 
  rowid_to_column() %>% 
  dual_axis_lines(rowid, mpg, cyl, disp, hp, facets = TRUE)

但是,生成的图的所有次要 y 轴变量都在第一个方面杂乱无章。

当我返回进入subplotp_facets 列表时,问题似乎不存在,因为每个图如下所示:

我该如何解决这个问题?

【问题讨论】:

标签: r plotly r-plotly


【解决方案1】:

好的,我按照this github issue about your bug.给出的思路来了

library(rlang)
library(plotly)
library(tibble)

dual_axis_lines <- function(data, x, y_left, ..., facets = FALSE, axes = NULL){
 x <- rlang::enquo(x)
 y_left <- rlang::enquo(y_left)
 y_right <- rlang::enquos(...)
 
## I removed some things here for simplicity, and because we want overlaying to vary between subplots.
 y_left_axparms <- list(
  tickfont = list(color = "#1f77b4"),
  side = "left")
 y_right_axparms <- list(
  side = "right")
 
 p <- plotly::plot_ly(data , x = x) %>%
  plotly::add_trace(y = y_left, name = quo_name(y_left),
                    yaxis = "y", type = 'scatter', mode = 'lines', 
                    line = list(color = "#1f77b4"))
 
 p_facets <- list()
## I needed to change the for loop so that i can have which plot index we are working with
 for(v in 1:length(y_right)){
  p_facets[[quo_name(y_right[[v]])]] <- p %>%
   plotly::add_trace(y = y_right[[v]], x = x, name = quo_name(y_right[[v]]),
                     yaxis = "y2", type = 'scatter', mode = 'lines') %>%
   plotly::layout(yaxis = y_left_axparms,
                 ## here is where you can assign each extra line to a particular subplot. 
                 ## you want overlaying to be: "y", "y3", "y5"... for each subplot
                  yaxis2 = append(y_right_axparms, c(overlaying = paste0(
                   "y", c("", as.character(seq(3,100,by = 2)))[v]))))
 }
 p <- subplot(p_facets, nrows = length(y_right), shareX = TRUE)
 return(p)
}

mtcars %>% 
 rowid_to_column() %>% 
 dual_axis_lines(rowid, mpg, cyl, disp, hp, facets = TRUE)


轴文本与线条颜色相同。

为此,您需要两件事。您需要在 for 循环之外为您的函数提供一个调色板:
color_palette &lt;- colorRampPalette(RColorBrewer::brewer.pal(10,"Spectral"))(length(y_right)) 如果你不喜欢调色板,你会改变它!

我已经清理了 for 循环,因此更易于查看。这就是它现在的样子,因此线条和轴文本共享相同的颜色:

 for(v in 1:length(y_right)){
  ## here is where you can assign each extra line to a particular subplot. 
  ## you want overlaying to be: "y", "y3", "y5"... for each subplot
  overlaying_location = paste0("y", c("", as.character(seq(3,100,by = 2)))[v])
  
  trace_name = quo_name(y_right[[v]])
  
  trace_value = y_right[[v]]
  
  trace_color = color_palette[v]
  
  p_facets[[trace_name]] <- p %>%
   plotly::add_trace(y = trace_value, 
                     x = x, 
                     name = trace_name,
                     yaxis = "y2", 
                     type = 'scatter', 
                     mode = 'lines', 
                     line = list(color = trace_color)) %>%
   plotly::layout(yaxis = y_left_axparms,
                  ## We can build the yaxis2 right here.
                  yaxis2 = eval(
                   parse(
                    text = "list(side = 'right', 
                            overlaying = overlaying_location, 
                            tickfont = list(color = trace_color))")
                  )
   )
 }

【讨论】:

  • 非常感谢!作为一个附带问题 - 你知道如何将右 y 轴刻度字体颜色设置为线条的颜色(即在这种特殊情况下为橙色、红色和棕色)?
猜你喜欢
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 2012-10-06
相关资源
最近更新 更多