首页 > 解决方案 > R:R中的“同步”图

问题描述

我正在使用 R 编程语言。我编写了以下代码来制作交互式时间序列“滑块”

 library(dplyr)
    library(ggplot2)
    library(shiny)
    library(plotly)
    library(htmltools)
    
    library(dplyr)
#generate data
set.seed(123)

var = rnorm(731, 100,25)
date= seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
data = data.frame(var,date)

vals <- 90:100
combine <- vector('list', length(vals))
count <- 0
for (i in vals) {
 
  data$var_i = i
  data$new_var_i = ifelse(data$var >i,1,0)
 
  #percent of observations greater than i (each month)
  aggregate_i = data %>%
    mutate(date = as.Date(date)) %>%
    group_by(month = format(date, "%Y-%m")) %>%
    summarise( mean = mean(new_var_i))
 
  #combine files together
 
  aggregate_i$var = i
  aggregate_i$var = as.factor(aggregate_i$var)
 
  count <- count + 1
  combine[[count]] <- aggregate_i
 
}

result_1 <- bind_rows(combine)
result_1$group = "group_a"
result_1$group = as.factor(result_1$group)

######

var = rnorm(731, 85,25)
date= seq(as.Date("2014/1/1"), as.Date("2016/1/1"),by="day")
data = data.frame(var,date)

vals <- 90:100
combine <- vector('list', length(vals))
count <- 0
for (i in vals) {
 
  data$var_i = i
  data$new_var_i = ifelse(data$var >i,1,0)
 
  #percent of observations greater than i (each month)
  aggregate_i = data %>%
    mutate(date = as.Date(date)) %>%
    group_by(month = format(date, "%Y-%m")) %>%
    summarise( mean = mean(new_var_i))
 
  #combine files together
 
  aggregate_i$var = i
  aggregate_i$var = as.factor(aggregate_i$var)
 
  count <- count + 1
  combine[[count]] <- aggregate_i
 
}

result_2 <- bind_rows(combine)
result_2$group = "group_b"
result_2$group = as.factor(result_2$group)

#combine all files

final = rbind(result_1, result_2)

gg <-ggplot(final, aes(frame = var, color = group)) + geom_line(aes(x=month, y=mean, group=1))+ theme(axis.text.x = element_text(angle=90)) + ggtitle("title")

gg = ggplotly(gg)

在此处输入图像描述

从这里,我想制作 3 个额外的图表,对应于滑块当前所在的“var”值。我在下面说明了这一点(对于 var = 90):

在此处输入图像描述

这是制作这 3 个附加图表所需的 R 代码(对于 var = 90):

#### filter for var = 90

a90 = final %>% 
  filter(var == 90)

a90 = a90 %>%
    group_by(group) %>%
    summarise( avg = mean(mean))

##bar plot

plot<-ggplot(data=a90, aes(x=group, y=avg)) +
  geom_bar(stat="identity") + ggtitle("bar plot")

bar_plotly <- ggplotly(plot)


#pie chart 
 Pie = ggplot(a90, aes(x="", y=(1-avg), fill=group)) +
      geom_bar(stat="identity", width=1) +
      coord_polar("y", start=0) +ggtitle( "Pie Chart") + scale_fill_brewer(palette="Blues")+
  theme_minimal()

#for some reason this does not work
pie_plotly = ggplotly(Pie)



#table

fig <- plot_ly(
  type = 'table',
  columnwidth = c(100, 100),
  columnorder = c(0, 1),
  header = list(
    values = c("average","group"),
    align = c("center", "center"),
    line = list(width = 1, color = 'black'),
    fill = list(color = c("grey", "grey")),
    font = list(family = "Arial", size = 14, color = "white")
  ),
  cells = list(
    values = rbind(a90$avg, a90$group),
    align = c("center", "center"),
    line = list(color = "black", width = 1),
    font = list(family = "Arial", size = 12, color = c("black"))
  ))

fig

我试图将所有图表放在一起,但这不起作用:

doc <- htmltools::tagList(
  div(gg, style = "float:left;width:50%;"),
  div(bar_plotly,style = "float:left;width:50%;"),
  div(fig, style = "float:left;width:50%;"))

htmltools::save_html(html = doc, file = "final.html")

Error in as.vector(x, "character") : 
  cannot coerce type 'environment' to vector of type 'character'

有人可以告诉我这是否可以在用户滑动第一个图表的滑块时更新其他图表?

谢谢

> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19041)

Matrix products: default

locale:
[1] LC_COLLATE=English_Canada.1252  LC_CTYPE=English_Canada.1252    LC_MONETARY=English_Canada.1252
[4] LC_NUMERIC=C                    LC_TIME=English_Canada.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shiny_1.6.0       htmltools_0.5.1.1 dplyr_1.0.3       plotly_4.9.3      ggplot2_3.3.3    

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.6         later_1.1.0.1      pillar_1.4.7       compiler_4.0.3     RColorBrewer_1.1-2 tools_4.0.3       
 [7] digest_0.6.27      jsonlite_1.7.2     lifecycle_0.2.0    tibble_3.0.5       gtable_0.3.0       viridisLite_0.3.0 
[13] pkgconfig_2.0.3    rlang_0.4.10       cli_2.2.0          rstudioapi_0.13    crosstalk_1.1.1    yaml_2.2.1        
[19] fastmap_1.1.0      withr_2.4.1        httr_1.4.2         generics_0.1.0     vctrs_0.3.6        htmlwidgets_1.5.3 
[25] grid_4.0.3         tidyselect_1.1.0   glue_1.4.2         data.table_1.13.6  R6_2.5.0           fansi_0.4.2       
[31] purrr_0.3.4        tidyr_1.1.2        farver_2.0.3       magrittr_2.0.1     promises_1.1.1     scales_1.1.1      
[37] ellipsis_0.3.1     assertthat_0.2.1   xtable_1.8-4       mime_0.9           colorspace_2.0-0   httpuv_1.5.5      
[43] labeling_0.4.2     lazyeval_0.2.2     munsell_0.5.0      crayon_1.3.4 

标签: rshinyplotlydata-visualizationinteractive

解决方案


根据plotly 的教程,组合不同情节的方法是使用subplot. 通过这样做,如果您在所有图中定义了 frame 参数,它还会将滑块链接到所有图(请参阅this other answer)。

另外,对于这些更复杂的情节,我认为直接在plotlyAPI 中工作总是更安全,而不是转换ggplot

# create summary dataframe for bar chart and pie chart
df.summary <- final %>% group_by(group, var) %>%
  summarise( avg = mean(mean)) %>% ungroup()

# create line chart
gg <- final %>% 
  plot_ly(x = ~month, y = ~mean, frame=~var, color=~group, type = 'scatter', mode = 'lines', colors = 'Set1') %>% 
  layout(showlegend = F)

# create bar chart
bar_plotly <- df.summary %>% 
  plot_ly(x = ~group, y = ~avg, frame=~var, color=~group, ids=groups, type = 'bar', colors = 'Set1') %>% 
  layout(showlegend = F, yaxis = list(range = c(0, 0.7)))

# create pie chart
Pie <- df.summary %>% 
  plot_ly(values = ~avg, frame=~var, ids=groups, type = 'pie', domain = list(x = c(0.6, 1), y = c(0, 0.4)), colors = 'Set1') %>% 
  layout(showlegend = F)

# combine all of them into one interactive plot
subplot(gg, subplot(bar_plotly, Pie, nrows = 2), nrows = 1)

在此处输入图像描述

根据 plotly,并非所有痕迹都完全支持动画。所以饼图中的过渡不会是平滑的。

另外,我认为您不能将表格与当前的 plotly API 链接起来。

另一种选择是创建一个闪亮的应用程序,您可以在其中拥有更多控制权。


推荐阅读