r - R:在图表之间切换
问题描述
我正在使用 R 编程语言。我正在尝试按照此处有关“在图表之间切换”的教程进行操作:https ://plotly.com/r/dropdowns/ (第一个示例)。
首先,我在 R 中生成了一些数据:
library(plotly)
library(MASS)
x <- sample( LETTERS[1:4], 1000, replace=TRUE, prob=c(0.25, 0.25, 0.25, 0.25) )
y <- rnorm(1000,10,10)
z <- rnorm(1000,5,5)
df <- data.frame(x,y, z)
df$x = as.factor(df$x)
colnames(df) <- c("x", "y", "z")
我尝试修改本教程中的代码以获得最终结果:
fig <- plot_ly(df, x = ~x, y = ~y, z = ~z alpha = 0.3)
fig <- fig %>% add_markers(marker = list(line = list(color = "black", width = 1)))
fig <- fig %>% layout(
title = "Drop down menus - Plot type",
xaxis = list(domain = c(0.1, 1)),
yaxis = list(title = "y"),
updatemenus = list(
list(
y = 0.8,
buttons = list(
list(method = "restyle",
args = list("type", "scatter"),
label = "Scatter A"),
list(method = "restyle",
args = list("type", "scatter"),
label = "Scatter B"),
list(method = "restyle",
args = list("type", "scatter"),
label = "Scatter C"),
list(method = "restyle",
args = list("type", "scatter"),
label = "Scatter D")
))
但这似乎不起作用。
相反,我有一个不同的想法:也许我可以创建一系列我希望能够在以下之间“切换”的图表:
df_1 <- df[which(df$x == "A"),]
df_2 <- df[which(df$x == "B"),]
df_3 <- df[which(df$x == "C"),]
df_4 <- df[which(df$x == "D"),]
graph_1 <- plot_ly( data = df_1, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 1")
graph_2 <- plot_ly( data = df_2, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 2")
graph_3 <- plot_ly( data = df_3, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 3")
graph_4 <- plot_ly( data = df_4, type = "scatter", mode = "markers", x = ~ y, y = ~z) %>% layout(title = "graph 4")
graph_5 <- plot_ly(df, y = ~y, color = ~x, type = "box") %>% layout(title = "boxplot")
现在,是否可以修改 plotly 代码以将所有这些图(graph_1、graph_2、graph_3、graph_4、graph_5)“绑定”在一起,以便用户可以单击左侧的选项卡并在这些图之间切换?
谢谢
解决方案
您应该查看本教程的示例是最后一个示例(带有正弦波)。它根据下拉菜单中的选择值隐藏和显示绘图的不同轨迹。
您只需要将数据框的格式更改为宽。
df.wide <- df %>% tidyr::pivot_wider(names_from = x, values_from=z)
df.wide
## A tibble: 1,000 x 5
# y D B A C
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 6.48 6.21 NA NA NA
# 2 23.6 NA 15.3 NA NA
# 3 -9.99 -2.16 NA NA NA
# 4 19.6 NA NA 0.0683 NA
# 5 18.8 -1.40 NA NA NA
# 6 -2.71 9.80 NA NA NA
# 7 2.32 NA NA NA 3.77
# 8 11.9 NA 4.35 NA NA
# 9 21.4 NA NA NA 13.9
#10 2.34 NA 2.10 NA NA
## … with 990 more rows
然后为每列添加单独的散点图。在下拉菜单的参数中,您可以设置在选择每个选项时哪些轨迹可见。例如args = list("visible", list(TRUE, FALSE, FALSE, FALSE))
意味着只有添加的第一个跟踪(在本例中为 column A
)将是可见的。
fig <- plot_ly(df.wide, x = ~y)
fig <- fig %>%
add_trace(y = ~A, name = "A", type='scatter', mode='markers') %>%
add_trace(y = ~B, name = "B", type='scatter', mode='markers', visible = F) %>%
add_trace(y = ~C, name = "C", type='scatter', mode='markers', visible = F) %>%
add_trace(y = ~D, name = "D", type='scatter', mode='markers', visible = F) %>%
layout(xaxis = list(domain = c(0.1, 1)),
yaxis = list(title = "y"),
updatemenus = list(
list(
y = 0.7,
buttons = list(
list(method = "restyle",
args = list("visible", list(TRUE, FALSE, FALSE, FALSE)),
label = "A"),
list(method = "restyle",
args = list("visible", list(FALSE, TRUE, FALSE, FALSE)),
label = "B"),
list(method = "restyle",
args = list("visible", list(FALSE, FALSE, TRUE, FALSE)),
label = "C"),
list(method = "restyle",
args = list("visible", list(FALSE, FALSE, FALSE, TRUE)),
label = "D")))))
编辑:还添加一个箱线图
为不同类型的图(如箱线图)添加一个选项有点困难。现在的问题是箱线图中的 x 轴和散点图中的 x 轴是不同的。所以你不能使用相同的轴。幸运的是,plotly 允许您将不同的轨迹映射到不同的轴。domain
然后,您可以使用该属性在完整图中设置此新轴的位置。
我的解决方案有点hacky,因为我使用该domain
属性来“隐藏”我不想使用的“情节”,方法是使其非常小(我还通过设置使相应的数据不可见visible = FALSE
)。这是因为隐藏轴只会隐藏线条。你仍然留下了情节的背景。
请注意,现在我使用该方法update
(而不是restyle
),因为它还允许您更改绘图的布局(https://plotly.com/r/custom-buttons/)。
但它似乎工作得很好!
# I had to reorder the dataframe because the boxplot was not following the order of the factors. Apparently it follows the orders that the letter appear.
df <- df %>% dplyr::arrange(x)
df.wide <- df %>% tidyr::pivot_wider(names_from = x, values_from=z)
# this is a list with axis config for scatter plot (define here to avoid repetition)
axis.config.scatter <- list(xaxis = list(title = "x", domain = c(0.1, 1), visible=T),
yaxis = list(title = "y", domain = c(0, 1), visible=T),
xaxis2 = list(title = "group", domain = c(0.99, 1), visible=F),
yaxis2 = list(title = "y", domain = c(0,99, 1), visible=F))
# this is a list with axis config for box plot (define here to avoid repetition)
axis.config.box <- list(xaxis = list(title = "x", domain = c(0.99, 1), visible=F),
yaxis = list(title = "y", domain = c(0.99, 1), visible=F),
xaxis2 = list(title = "group", domain = c(0.1, 1), visible=T, anchor='free'),
yaxis2 = list(title = "y", domain = c(0, 1), visible=T, anchor='free'))
fig <- plot_ly(df.wide)
fig <- fig %>%
add_trace(x = ~y, y = ~A, name = "A", type='scatter', mode='markers') %>%
add_trace(x = ~y, y = ~B, name = "B", type='scatter', mode='markers', visible = F) %>%
add_trace(x = ~y, y = ~C, name = "C", type='scatter', mode='markers', visible = F) %>%
add_trace(x = ~y, y = ~D, name = "D", type='scatter', mode='markers', visible = F) %>%
add_trace(data=df, x=~x, y=~z, name='box', type='box', visible=F, xaxis='x2', yaxis='y2') %>%
layout(xaxis = list(title = "x", domain = c(0.1, 1)),
yaxis = list(title = "y"),
xaxis2 = list(title = "group", domain = c(0.99, 1), visible=F),
yaxis2 = list(title = "y", domain = c(0.99, 1), visible=F),
updatemenus = list(
list(
y = 0.7,
buttons = list(
list(method = "update",
args = list(list(visible = c(TRUE, FALSE, FALSE, FALSE, FALSE)),
axis.config.scatter),
label = "A"),
list(method = "update",
args = list(list(visible = c(FALSE, TRUE, FALSE, FALSE, FALSE)),
axis.config.scatter),
label = "B"),
list(method = "update",
args = list(list(visible = c(FALSE, FALSE, TRUE, FALSE, FALSE)),
axis.config.scatter),
label = "C"),
list(method = "update",
args = list(list(visible = c(FALSE, FALSE, FALSE, TRUE, FALSE)),
axis.config.scatter),
label = "D"),
list(method = "update",
args = list(list(visible = c(FALSE, FALSE, FALSE, FALSE, TRUE)),
axis.config.box),
label = "box")
))))
推荐阅读
- amazon-web-services - EKS 工作节点 IAM 角色优先于 POD 的 serviceaccount IAM 角色
- r - RecordLinkage 包 jarowinkler 没有输出
- python - Selenium 不能在 Mac OSX High Sierra 上与 Python 一起使用。更新:仅在通过终端启动 IDLE 时有效,否则无法找到所有路径
- python - 如何在 Python 中将 BufferedWriter 转换为字节数组?
- python - 正则表达式:结果不符合预期
- javascript - 赛普拉斯支持 Typescript:它的真正含义是什么?
- java - 用神经网络对网页进行分类?
- python - PyQt5 菜单栏、背景和拖动主窗口
- flutter - Flutter:条件开关和从列表中添加/删除
- python - 带有 CountVectorizer 和附加预测器的 sklearn DecisionTreeClassifier