英文:
R Shiny: the legend splits when renderPlotly is used
问题
我注意到一个奇怪的现象,renderPlotly
可以将相同变量的图例分开。
例如,当使用renderPlot()
时,生成的图表如下所示:
然而,如果我尝试将其转换为Plotly对象,它会变成这样:
有人知道发生了什么,以及如何解决这个问题吗?谢谢!
英文:
I noticed a strange phenomenon that renderPlotly can split the legend of the same variable.
For example, when renderPlot() is used, the produced graph looks like this:
However, if I tried to convert it into a plotly object, it changed into this:
Does anyone know what is going on and how to fix this problem? Thank you!
ggplot version:
library(shiny)
library(plotly)
ColorblindnessFriendlyValues <- c("Same" = "#648FFF", "Alt" = "#FFB000")
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("crossloadings", "Number Crossloadings",
min = 1, max = 10, value = 5),
sliderInput("group1", "Group 1",
min = 0, max = 1, value = 0.5),
sliderInput("group2", "Group 2",
min = 0, max = 1, value = 0.5)
),
mainPanel(
plotlyOutput("plot") # Changed here
)
)
)
server <- function(input, output) {
output$plot <- renderPlotly({
number_crossloadings <- seq(1, input$crossloadings)
group1 <- runif(input$crossloadings, min = 0, max = input$group1)
group2 <- runif(input$crossloadings, min = 0, max = input$group2)
results <- data.frame(number_crossloadings, group1, group2)
plot <- ggplot(data=results, aes(x=number_crossloadings))+
geom_line(aes(y=group1,
color="Same"))+
geom_line(aes(y=group2,color="Alt"))+
suppressWarnings(geom_point(aes(y=group1,
color="Same",
shape = "Same",
text = paste0("# of cross Loadings: ", number_crossloadings,
"<br>SRMR: ", sprintf('%.3f', group1)))))+
suppressWarnings(geom_point(aes(y=group2,
color="Alt",
shape = "Alt",
text = paste0("# of cross Loadings: ", number_crossloadings,
"<br>SRMR: ", sprintf('%.3f', group2)))))+
scale_color_manual(values = ColorblindnessFriendlyValues, labels = c("Same", "Alt")) +
scale_shape_manual(values = c("Same" = 16, "Alt" = 17), labels = c("Same", "Alt")) +
geom_abline(color="grey",slope=0, intercept=0.08) +
labs(color = "Legend", shape = "Legend") +
ylim(NA,1)
ggplotly(plot,tooltip = c("text"))
})
}
shinyApp(ui, server)
Plotly version:
library(shiny)
library(plotly)
ColorblindnessFriendlyValues <- c("Same" = "#648FFF", "Alt" = "#FFB000")
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("crossloadings", "Number Crossloadings",
min = 1, max = 10, value = 5),
sliderInput("group1", "Group 1",
min = 0, max = 1, value = 0.5),
sliderInput("group2", "Group 2",
min = 0, max = 1, value = 0.5)
),
mainPanel(
plotOutput("plot")
)
)
)
server <- function(input, output) {
output$plot <- renderPlot({
number_crossloadings <- seq(1, input$crossloadings)
group1 <- runif(input$crossloadings, min = 0, max = input$group1)
group2 <- runif(input$crossloadings, min = 0, max = input$group2)
results <- data.frame(number_crossloadings, group1, group2)
plot <- ggplot(data=results, aes(x=number_crossloadings))+
geom_line(aes(y=group1, color="Same"))+
geom_line(aes(y=group2,color="Alt"))+
suppressWarnings(geom_point(aes(y=group1,
color="Same",
shape = "Same",
text = paste0("# of cross Loadings: ", number_crossloadings,
"<br>SRMR: ", sprintf('%.3f', group1)))))+
suppressWarnings(geom_point(aes(y=group2,
color="Alt",
shape = "Alt",
text = paste0("# of cross Loadings: ", number_crossloadings,
"<br>SRMR: ", sprintf('%.3f', group2)))))+
scale_color_manual(values = ColorblindnessFriendlyValues, labels = c("Same", "Alt")) +
scale_shape_manual(values = c("Same" = 16, "Alt" = 17), labels = c("Same", "Alt")) +
geom_abline(color="grey",slope=0, intercept=0.08) +
labs(color = "Legend", shape = "Legend") +
ylim(NA,1)
plot
})
}
shinyApp(ui, server)
答案1
得分: 1
Whenever the translation ggplot
<-> plotly
does not yield the results I want, I use plot_ly
directly as it allows for finer control.
Having said that, you can generate a similar plot with plot_ly
like this (N.B. I changed your data structure a bit to avoid some duplication):
output$plot <- renderPlotly({
number_crossloadings <- seq(1, input$crossloadings)
group1 <- runif(input$crossloadings, min = 0, max = input$group1)
group2 <- runif(input$crossloadings, min = 0, max = input$group2)
results <- data.frame(x = rep(number_crossloadings, 2),
y = c(group1, group2),
g = rep(c("Same", "Alt"), each = input$crossloadings))
plot_ly(results,
x = ~ x,
y = ~ y,
colors = ColorblindnessFriendlyValues,
symbols = c("triangle-up", "circle")) %>%
add_trace(type = "scatter",
mode = "lines",
showlegend = FALSE,
hoverinfo = "none",
color = I("gray"),
x = range(results$x) + c(-1, 1) * .2,
y = c(.08, .08)) %>%
add_trace(type = "scatter",
mode = "markers+lines",
color = ~ g,
symbol = ~ g,
marker = list(size = 8),
hoverinfo = "text",
text = ~ paste0("# of cross Loadings: ", number_crossloadings,
"<br>SRMR: ", sprintf("%.3f", y))) %>%
layout(legend = list(title = list(text = "Legend")),
xaxis = list(title = list(text = "number_crossloadings")),
yaxis = list(title = list(text = "y")))
})
Abline
I used a separate trace for the abline
, another option would be to add a shape
to layout
like this:
layout(
#...
shapes = list(
list(
type = "rect",
x0 = 0,
x1 = 1,
xref = "paper",
y0 = 0.08,
y1 = 0.08,
yref = "y",
line = list(dash = "solid",
color = "grey"),
layer = "below"
)
)
)
英文:
Whenever the translation ggplot
<-> plotly
does not yield the results I want, I use plot_ly
directly as it allows for finer control.
Having said that, you can generate a similar plot with plot_ly
like this (N.B. I changed your data structure a bit to avoid some duplication):
output$plot <- renderPlotly({
number_crossloadings <- seq(1, input$crossloadings)
group1 <- runif(input$crossloadings, min = 0, max = input$group1)
group2 <- runif(input$crossloadings, min = 0, max = input$group2)
results <- data.frame(x = rep(number_crossloadings, 2),
y = c(group1, group2),
g = rep(c("Same", "Alt"), each = input$crossloadings))
plot_ly(results,
x = ~ x,
y = ~ y,
colors = ColorblindnessFriendlyValues,
symbols = c("triangle-up", "circle")) %>%
add_trace(type = "scatter",
mode = "lines",
showlegend = FALSE,
hoverinfo = "none",
color = I("gray"),
x = range(results$x) + c(-1, 1) * .2,
y = c(.08, .08)) %>%
add_trace(type = "scatter",
mode = "markers+lines",
color = ~ g,
symbol = ~ g,
marker = list(size = 8),
hoverinfo = "text",
text = ~ paste0("# of cross Loadings: ", number_crossloadings,
"<br>SRMR: ", sprintf("%.3f", y))) %>%
layout(legend = list(title = list(text = "Legend")),
xaxis = list(title = list(text = "number_crossloadings")),
yaxis = list(title = list(text = "y"))
})
Abline
I used a separate trace for the abline
, another option would be to add a shape
to layout
like this:
layout(
#...
shapes = list(
list(
type = "rect",
x0 = 0,
x1 = 1,
xref = "paper",
y0 = 0.08,
y1 = 0.08,
yref = "y",
line = list(dash = "solid",
color = "grey"),
layer = "below"
)
)
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论