如何在 Plotly 中使用高亮功能在 y1 和 y2 轴上有 2 条轨迹
Posted
技术标签:
【中文标题】如何在 Plotly 中使用高亮功能在 y1 和 y2 轴上有 2 条轨迹【英文标题】:How to have 2 traces on y1 & y2 axis with highlight function in Plotly 【发布时间】:2021-12-21 07:59:33 【问题描述】:我需要绘制 2 条轨迹,一条在左侧 y 轴,一条在右侧,我想保留高亮功能。因此,data
参数对于两个跟踪是不同的。
有没有办法做到这一点?
library(plotly)
## Data ################
tmp <- data.frame(timestamp = structure(c(1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200,
1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200),
class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin"),
value = c(29.015, 25.724, 24.017, 25.118, 28.334, 30.408,
32.046, 32.441, 29.463, 27.528, 24.136, 21.067, 27.352, 23.13,
24.962, 24.558, 130.475, 148.465, 157.134, 149.983, 133.003,
123.9, 117.334, 115.927),
valuetype = c(rep("Type 1",12),rep("Type 2",12)),
route_name = rep("group 1", 24),
value_color = c(rep("#e3a201", 12), rep("#FFBA00",12)))
## Plotly ###############
plot_ly(data = tmp) %>%
highlight_key(~paste0(route_name, valuetype)) %>%
## 1 Trace ###################
add_trace(
data = tmp[tmp$valuetype %in% unique(tmp$valuetype)[[1]],],
inherit = FALSE,
x = ~timestamp, y = ~value,
type = "scattergl", mode = "lines",
name = ~paste(valuetype, route_name),
color = ~I(value_color)) %>%
## 2 Trace ###################
add_trace(
data = tmp[tmp$valuetype %in% unique(tmp$valuetype)[[2]],],
inherit = FALSE,
x = ~timestamp, y = ~value,
yaxis = "y2",
type = "scattergl", mode = "lines",
name = ~paste(valuetype, route_name),
color = ~I(value_color)) %>%
## Layout for Group 1&2 ###################
plotly::layout(xaxis = list(title = "Zeit", type = "date"),
yaxis = list(side ="left", title = "Y-Title"),
yaxis2 = list(side="right", overlaying = "y", title = "Y2-Title"),
margin = list(l=50,r=50,t=50,b=10),
legend = list(orientation = 'h', xanchor = 'center', x = 0.5, y = -0.2)) %>%
plotly::highlight(on = "plotly_hover", off = "plotly_doubleclick",
selected = attrs_selected(showlegend = FALSE))
【问题讨论】:
【参考方案1】:不确定这是否适合您,但如果您只使用单个 data
参数,您可以使用 style
将轨迹分配给另一个 y 轴:
library(plotly)
## Data ################
tmp <- data.frame(timestamp = structure(c(1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200,
1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200),
class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin"),
value = c(29.015, 25.724, 24.017, 25.118, 28.334, 30.408,
32.046, 32.441, 29.463, 27.528, 24.136, 21.067, 27.352, 23.13,
24.962, 24.558, 130.475, 148.465, 157.134, 149.983, 133.003,
123.9, 117.334, 115.927),
valuetype = c(rep("Type 1",12),rep("Type 2",12)),
route_name = rep("group 1", 24),
value_color = c(rep("#e3a201", 12), rep("#FFBA00",12)))
## Plotly ###############
tmp %>% highlight_key(~paste0(route_name, valuetype)) %>%
plot_ly(
x = ~timestamp, y = ~value,
type = "scatter", mode = "lines", # "scattergl"
name = ~paste(valuetype, route_name),
color = ~I(value_color)) %>%
## assign trace 1 to y2
style(yaxis = "y2", traces = 1) %>%
## Layout for Group 1&2 ###################
plotly::layout(xaxis = list(title = "Zeit", type = "date"),
yaxis = list(side ="left", title = "Y-Title"),
yaxis2 = list(side="right", overlaying = "y", title = "Y2-Title"),
margin = list(l=50,r=50,t=50,b=10),
legend = list(orientation = 'h', xanchor = 'center', x = 0.5, y = -0.2)) %>%
plotly::highlight(on = "plotly_hover", off = "plotly_doubleclick", selected = attrs_selected(showlegend = FALSE))
编辑:跟踪索引示例:
library(plotly)
library(data.table)
## Data ################
tmp <- data.frame(timestamp = structure(c(1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200,
1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200,
1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200,
1632132000, 1632139200, 1632146400, 1632153600, 1632160800, 1632168000,
1632175200, 1632182400, 1632189600, 1632196800, 1632204000, 1632211200),
class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin"),
value = c(c(29.015, 25.724, 24.017, 25.118, 28.334, 30.408,
32.046, 32.441, 29.463, 27.528, 24.136, 21.067, 27.352, 23.13,
24.962, 24.558, 130.475, 148.465, 157.134, 149.983, 133.003,
123.9, 117.334, 115.927), c(29.015, 25.724, 24.017, 25.118, 28.334, 30.408,
32.046, 3.441, 2.463, 2.528, 2.136, 2.067, 2.352, 23.13,
24.962, 24.558, 13.475, 14.465, 15.134, 14.983, 13.003,
123.9, 117.334, 115.927) + 50),
valuetype = c(rep("Type 1",12), rep("Type 2", 12), rep("Type 3", 12), rep("Type 4", 12)),
route_name = rep("group 1", 48),
value_color = c(rep("#e3a201", 12), rep("#FFBA00", 12), rep("red", 12), rep("darkgreen", 12)),
yaxis = c(rep("y", 12), rep("y2", 12), rep("y", 12), rep("y3", 12)))
setDT(tmp)
tmp[, trace_index := .GRP-1, by = .(route_name, valuetype)]
## Plotly ###############
shared_data <- highlight_key(tmp, ~paste0(route_name, valuetype))
fig <- plot_ly(data = shared_data,
x = ~timestamp, y = ~value,
type = "scatter", mode = "lines", # "scattergl"
name = ~paste(valuetype, route_name),
color = ~I(value_color))
if(any(tmp$yaxis != "y"))
axesMapping <- unique(tmp[yaxis != "y", c("yaxis","trace_index")])
# layout call to add the axis could be added here
for(i in seq_len(NROW(axesMapping)))
fig <- do.call(plotly::style, list(p = fig, yaxis = axesMapping[i,]$yaxis, traces = axesMapping[i,]$trace_index))
## Layout for Group 1&2 ###################
plotly::layout(fig,
xaxis = list(title = "Zeit", type = "date", domain = c(0, 0.75)),
yaxis = list(side ="left", title = "Y-Title"),
yaxis2 = list(side="right", overlaying = "y", title = "Y2-Title"),
yaxis3 = list(side="right", overlaying = "y", anchor="free", position = 0.85, title = "Y3-Title"),
margin = list(l=50,r=50,t=50,b=10),
legend = list(orientation = 'h', xanchor = 'center', x = 0.5, y = -0.2)) %>%
plotly::highlight(on = "plotly_hover", off = "plotly_doubleclick", selected = attrs_selected(showlegend = FALSE))
【讨论】:
这是个好主意,但我不确定我是否可以使用它,因为绘图可以有多个轨迹,有时带有第二个 y 轴,有时没有.. 我不知道我是否可以预先知道 y2 的跟踪指数。 跟踪索引的顺序应该与你的数据顺序相对应——所以应该可以。但是,different trace types 有一个限制。 @SeGa 我添加了一个关于跟踪索引的更复杂的示例。以上是关于如何在 Plotly 中使用高亮功能在 y1 和 y2 轴上有 2 条轨迹的主要内容,如果未能解决你的问题,请参考以下文章
Plotly:如何在 Plotly 中绘制具有渐变颜色的矩形?