如何将子图应用于具有次要 y 轴的图列表
How to apply subplot to a list of plots with secondary y axis
我想准备一个子图,其中每个方面都是一个变量相对于其他变量的独立双 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 轴变量都在第一个方面杂乱无章。
当我 return p_facets
列出进入 subplot
时,问题似乎不存在,因为每个图如下所示:
我该如何解决这个问题?
好的,我遵循了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-loop:
之外为您的函数提供调色板
color_palette <- colorRampPalette(RColorBrewer::brewer.pal(10,"Spectral"))(length(y_right))
如果您不喜欢调色板,您可以更改它!
我已经清理了 for-loop 以便更容易查看。这就是现在的样子,因此线条和轴文本共享相同的颜色:
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 轴图。所以我制作了一个基本图 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 轴变量都在第一个方面杂乱无章。
当我 return p_facets
列出进入 subplot
时,问题似乎不存在,因为每个图如下所示:
我该如何解决这个问题?
好的,我遵循了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-loop:
之外为您的函数提供调色板
color_palette <- colorRampPalette(RColorBrewer::brewer.pal(10,"Spectral"))(length(y_right))
如果您不喜欢调色板,您可以更改它!
我已经清理了 for-loop 以便更容易查看。这就是现在的样子,因此线条和轴文本共享相同的颜色:
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))")
)
)
}