使用 Shiny App 的气泡图 - 标签和气泡不同步
Bubble Chart using Shiny App - Labels and Bubbles out of sync
首先是我的数据:
df <- structure(list(rowname = c(
"AA - 2018", "AA - 2019", "AA - 2020",
"AB - 2018", "AB - 2019", "AB - 2020"
), Class = c(
"AA", "AA",
"AA", "AB", "AB", "AB"
), Year = c(
2018L, 2019L, 2020L, 2018L,
2019L, 2020L
), Vol = c(0.3, 0.4, 0.5, 0.2, 0.4, 0.7), Profit = c(
-0.1,
-0.4, 0.2, 0.5, 0.2, -0.9
), Amount = c(1L, 1L, 2L, 3L, 4L, 5L), Division = c("Bonds","Bonds","Bonds","Equity","Equity","Equity")), class = "data.frame", row.names = c(NA, -6L))
我正在尝试创建一个气泡图,其中气泡的大小取决于金额,并根据 x 轴上的盈利能力(占金额的百分比)和波动率(作为% 的数量)在 y 轴上。我添加了一个使用年份列的滑块,这样气泡就可以随着滑块年份的变化而变化。
我正在开发一个带有下拉框的闪亮应用程序,允许使用 select 一个部门或所有部门。我有两个问题:
我希望轴随下拉框一起改变 selection 并且这有效但不幸的是标签和气泡不同步(在某些情况下消失)我移动滑块。当我注释掉 RenderPlotly 部分开头的条件时,气泡和标签不会不同步。
有没有更好的方法来编写条件部分而不使用 if 语句?
divvar = c("All"="All","Bond"="Bond","Equity"="Equity")
Bound <- 0.1
y_high <- max(df$Vol) + Bound
y_low <- 0
x_high <-max(df$Profit) + Bound
x_low <- min(df$Profit) -Bound
ui <- shinyUI(fluidPage(
titlePanel("Title"), # Application title
sidebarLayout(
sidebarPanel(
selectInput("Division","Select Division",divvar,selected = "All"),width=2),
mainPanel(plotlyOutput("plot", width = "100%"))
)
)
)
server <- function(input, output) {
output$plot <- renderPlotly({
#Labels and Bubbles are in sync if below section is commented:
#----
fil_table <- df %>% select(Vol,Profit,Division) %>% filter (Division == input$Division)
if(input$Division == "All") {}
else
{y_high <- max(fil_table$Vol) + Bound
x_high <- max(fil_table$Profit) + Bound
x_low <- min(fil_table$Profit) + Bound
}
#----
ggplotly(ggplot( if(input$Division == "All") {df}
else
{df %>% filter (Division == input$Division)},
aes(x = Profit, y = Vol, size = Amount, color = Class, frame = Year)) +
geom_point(alpha = 0.2) + scale_size(range = c(5,40)) +
geom_text(aes(label = Class), size = 5)+
geom_vline(xintercept = 0, linetype="dotted", color = "black", size=0.75)+
scale_y_continuous(labels = scales::percent,expand = c(0, 0), limits = c(0,y_high)) +
scale_x_continuous(labels = scales::percent,expand = c(0, 0), limits = c(x_low,x_high)) +
labs(title = "Profitability vs Volatility",
x = "Profitability %",
y = "Volatility %")
})
}
shinyApp(ui=ui, server=server)
如果选择 Bounds/Equity
,您计算的下限是错误的,您使用 +
而不是 -
。一般来说,使用if/else
是可以的,但我不会直接在ggplot
调用中使用它,所以我简化了一点。我建议您查看并使用 风格指南来编写可读性更好的代码,例如 tidyverse style guide.
df <- structure(list(rowname = c(
"AA - 2018", "AA - 2019", "AA - 2020",
"AB - 2018", "AB - 2019", "AB - 2020"
), Class = c(
"AA", "AA",
"AA", "AB", "AB", "AB"
), Year = c(
2018L, 2019L, 2020L, 2018L,
2019L, 2020L
), Vol = c(0.3, 0.4, 0.5, 0.2, 0.4, 0.7), Profit = c(
-0.1,
-0.4, 0.2, 0.5, 0.2, -0.9
), Amount = c(1L, 1L, 2L, 3L, 4L, 5L), Division = c("Bonds","Bonds","Bonds","Equity","Equity","Equity")), class = "data.frame", row.names = c(NA, -6L))
divvar = c("All"="All","Bonds"="Bonds","Equity"="Equity")
Bound <- 0.1
y_high <- max(df$Vol) + Bound
y_low <- 0
x_high <-max(df$Profit) + Bound
x_low <- min(df$Profit) -Bound
library(shiny)
library(plotly)
ui <- shinyUI(fluidPage(
titlePanel("Title"), # Application title
sidebarLayout(
sidebarPanel(
selectInput("Division","Select Division",divvar,selected = "All"),width=2),
mainPanel(plotlyOutput("plot", width = "100%"))
)
)
)
server <- function(input, output) {
output$plot <- renderPlotly({
if (input$Division == "All") {
plot_data <- df
} else {
plot_data <- df %>% filter(Division == input$Division)
y_high <- max(plot_data$Vol) + Bound
x_high <- max(plot_data$Profit) + Bound
x_low <- min(plot_data$Profit) - Bound
}
ggplotly(ggplot(plot_data,
aes(x = Profit, y = Vol, size = Amount, color = Class, frame = Year)) +
geom_point(alpha = 0.2) + scale_size(range = c(5,40)) +
geom_text(aes(label = Class), size = 5)+
geom_vline(xintercept = 0, linetype="dotted", color = "black", size=0.75)+
scale_y_continuous(labels = scales::percent,expand = c(0, 0), limits = c(0,y_high)) +
scale_x_continuous(labels = scales::percent,expand = c(0, 0), limits = c(x_low,x_high)) +
labs(title = "Profitability vs Volatility",
x = "Profitability %",
y = "Volatility %"))
})
}
shinyApp(ui=ui, server=server)
首先是我的数据:
df <- structure(list(rowname = c(
"AA - 2018", "AA - 2019", "AA - 2020",
"AB - 2018", "AB - 2019", "AB - 2020"
), Class = c(
"AA", "AA",
"AA", "AB", "AB", "AB"
), Year = c(
2018L, 2019L, 2020L, 2018L,
2019L, 2020L
), Vol = c(0.3, 0.4, 0.5, 0.2, 0.4, 0.7), Profit = c(
-0.1,
-0.4, 0.2, 0.5, 0.2, -0.9
), Amount = c(1L, 1L, 2L, 3L, 4L, 5L), Division = c("Bonds","Bonds","Bonds","Equity","Equity","Equity")), class = "data.frame", row.names = c(NA, -6L))
我正在尝试创建一个气泡图,其中气泡的大小取决于金额,并根据 x 轴上的盈利能力(占金额的百分比)和波动率(作为% 的数量)在 y 轴上。我添加了一个使用年份列的滑块,这样气泡就可以随着滑块年份的变化而变化。
我正在开发一个带有下拉框的闪亮应用程序,允许使用 select 一个部门或所有部门。我有两个问题:
我希望轴随下拉框一起改变 selection 并且这有效但不幸的是标签和气泡不同步(在某些情况下消失)我移动滑块。当我注释掉 RenderPlotly 部分开头的条件时,气泡和标签不会不同步。
有没有更好的方法来编写条件部分而不使用 if 语句?
divvar = c("All"="All","Bond"="Bond","Equity"="Equity") Bound <- 0.1 y_high <- max(df$Vol) + Bound y_low <- 0 x_high <-max(df$Profit) + Bound x_low <- min(df$Profit) -Bound ui <- shinyUI(fluidPage( titlePanel("Title"), # Application title sidebarLayout( sidebarPanel( selectInput("Division","Select Division",divvar,selected = "All"),width=2), mainPanel(plotlyOutput("plot", width = "100%")) ) ) ) server <- function(input, output) { output$plot <- renderPlotly({ #Labels and Bubbles are in sync if below section is commented: #---- fil_table <- df %>% select(Vol,Profit,Division) %>% filter (Division == input$Division) if(input$Division == "All") {} else {y_high <- max(fil_table$Vol) + Bound x_high <- max(fil_table$Profit) + Bound x_low <- min(fil_table$Profit) + Bound } #---- ggplotly(ggplot( if(input$Division == "All") {df} else {df %>% filter (Division == input$Division)}, aes(x = Profit, y = Vol, size = Amount, color = Class, frame = Year)) + geom_point(alpha = 0.2) + scale_size(range = c(5,40)) + geom_text(aes(label = Class), size = 5)+ geom_vline(xintercept = 0, linetype="dotted", color = "black", size=0.75)+ scale_y_continuous(labels = scales::percent,expand = c(0, 0), limits = c(0,y_high)) + scale_x_continuous(labels = scales::percent,expand = c(0, 0), limits = c(x_low,x_high)) + labs(title = "Profitability vs Volatility", x = "Profitability %", y = "Volatility %") }) } shinyApp(ui=ui, server=server)
如果选择 Bounds/Equity
,您计算的下限是错误的,您使用 +
而不是 -
。一般来说,使用if/else
是可以的,但我不会直接在ggplot
调用中使用它,所以我简化了一点。我建议您查看并使用 风格指南来编写可读性更好的代码,例如 tidyverse style guide.
df <- structure(list(rowname = c(
"AA - 2018", "AA - 2019", "AA - 2020",
"AB - 2018", "AB - 2019", "AB - 2020"
), Class = c(
"AA", "AA",
"AA", "AB", "AB", "AB"
), Year = c(
2018L, 2019L, 2020L, 2018L,
2019L, 2020L
), Vol = c(0.3, 0.4, 0.5, 0.2, 0.4, 0.7), Profit = c(
-0.1,
-0.4, 0.2, 0.5, 0.2, -0.9
), Amount = c(1L, 1L, 2L, 3L, 4L, 5L), Division = c("Bonds","Bonds","Bonds","Equity","Equity","Equity")), class = "data.frame", row.names = c(NA, -6L))
divvar = c("All"="All","Bonds"="Bonds","Equity"="Equity")
Bound <- 0.1
y_high <- max(df$Vol) + Bound
y_low <- 0
x_high <-max(df$Profit) + Bound
x_low <- min(df$Profit) -Bound
library(shiny)
library(plotly)
ui <- shinyUI(fluidPage(
titlePanel("Title"), # Application title
sidebarLayout(
sidebarPanel(
selectInput("Division","Select Division",divvar,selected = "All"),width=2),
mainPanel(plotlyOutput("plot", width = "100%"))
)
)
)
server <- function(input, output) {
output$plot <- renderPlotly({
if (input$Division == "All") {
plot_data <- df
} else {
plot_data <- df %>% filter(Division == input$Division)
y_high <- max(plot_data$Vol) + Bound
x_high <- max(plot_data$Profit) + Bound
x_low <- min(plot_data$Profit) - Bound
}
ggplotly(ggplot(plot_data,
aes(x = Profit, y = Vol, size = Amount, color = Class, frame = Year)) +
geom_point(alpha = 0.2) + scale_size(range = c(5,40)) +
geom_text(aes(label = Class), size = 5)+
geom_vline(xintercept = 0, linetype="dotted", color = "black", size=0.75)+
scale_y_continuous(labels = scales::percent,expand = c(0, 0), limits = c(0,y_high)) +
scale_x_continuous(labels = scales::percent,expand = c(0, 0), limits = c(x_low,x_high)) +
labs(title = "Profitability vs Volatility",
x = "Profitability %",
y = "Volatility %"))
})
}
shinyApp(ui=ui, server=server)