在R Shiny应用程序中渲染ggplot2和一个可绘制对象

如何解决在R Shiny应用程序中渲染ggplot2和一个可绘制对象

我有一个R shiny应用程序,它同时使用R的{​​{1}}和plotly来生成和显示图形。

由于要在ggplot2中绘制plotly图形需要shiny的{​​{1}}函数,因此plotly图形被转换为renderPlotly对象。 ggplot2部分,将它们弄乱了。

这是一个例子。 首先,生成一些数据:

plotly

这是应用程序代码:

renderPlotly

如果用户选择set.seed(1) meta.df <- data.frame(cell = c(paste0("c_",1:1000,"_1w"),paste0("c_","_2w"),"_3w")),cluster = c(sample(c("cl1","cl2","cl3"),1000,replace=T)),age = c(rep(1,1000),rep(2,rep(3,1000)),x = rnorm(3000),y = rnorm(3000)) expression.mat <- cbind(matrix(rnorm(20*1000,1,1),nrow=20,ncol=1000,dimnames=list(paste0("g",1:20),meta.df$cell[1:1000])),matrix(rnorm(20*1000,2,meta.df$cell[1001:2000])),3,meta.df$cell[2001:3000]))) library(shiny) library(dplyr) library(ggplot2) library(ggpmisc) server <- function(input,output,session) { output$gene <- renderUI({ selectInput("gene","Select Gene to Display",choices = rownames(expression.mat)) }) output$group <- renderUI({ if(input$plotType == "Distribution Plot"){ selectInput("group","Select Group",choices = c("cluster","age")) } }) scatter.plot <- reactive({ scatter.plot <- NULL if(!is.null(input$gene)){ gene.idx <- which(rownames(expression.mat) == input$gene) plot.df <- suppressWarnings(meta.df %>% dplyr::left_join(data.frame(cell=colnames(expression.mat),value=expression.mat[gene.idx,]),by=c("cell"="cell"))) scatter.plot <- suppressWarnings(plotly::plot_ly(marker=list(size=3),type='scatter',mode="markers",color=plot.df$value,x=plot.df$x,y=plot.df$y,showlegend=F,colors=colorRamp(c("lightgray","darkred"))) %>% plotly::layout(title=input$gene,xaxis=list(zeroline=F,showticklabels=F,showgrid=F),yaxis=list(zeroline=F,showgrid=F)) %>% plotly::colorbar(limits=c(min(plot.df$value,na.rm=T),max(plot.df$value,na.rm=T)),len=0.4,title="Scaled Expression")) } return(scatter.plot) }) distribution.plot <- reactive({ distribution.plot <- NULL if(!is.null(input$gene) & !is.null(input$group)){ gene.idx <- which(rownames(expression.mat) == input$gene) plot.df <- suppressWarnings(meta.df %>% dplyr::left_join(data.frame(cell=colnames(expression.mat),by=c("cell"="cell"))) if(input$group == "cluster"){ distribution.plot <- suppressWarnings(plotly::plot_ly(x=plot.df$cluster,y=plot.df$value,split=plot.df$cluster,type='violin',box=list(visible=T),points=T,color=plot.df$cluster,showlegend=F) %>% plotly::layout(title=input$gene,xaxis=list(title=input$group,zeroline=F),yaxis=list(title="Scaled Expression",zeroline=F))) } else{ plot.df <- plot.df %>% dplyr::mutate(time=age) %>% dplyr::arrange(time) plot.df$age <- factor(plot.df$age,levels=unique(plot.df$age)) distribution.plot <- suppressWarnings(ggplot(plot.df,aes(x=time,y=value)) + geom_violin(aes(fill=age,color=age),alpha=0.3) + geom_boxplot(width=0.1,aes(color=age),fill=NA) + geom_smooth(mapping=aes(x=time,y=value,group=cluster),color="black",method='lm',size=1,se=T) + stat_poly_eq(mapping=aes(x=time,group=cluster,label=stat(p.value.label)),formula=y~x,parse=T,npcx="center",npcy="bottom") + scale_x_discrete(name=NULL,labels=levels(plot.df$cluster),breaks=unique(plot.df$time)) + facet_wrap(~cluster) + theme_minimal() + ylab(paste0("#",input$gene," Scaled Expressioh"))+theme(legend.title=element_blank())) } } return(distribution.plot) }) output$out.plot <- plotly::renderPlotly({ if(input$plotType == "Scatter Plot"){ scatter.plot() } else if(input$plotType == "Distribution Plot"){ distribution.plot() } }) } ui <- fluidPage( titlePanel("Explorer"),sidebarLayout( sidebarPanel( tags$head( tags$style(HTML(".multicol {-webkit-column-count: 3; /* Chrome,Safari,Opera */-moz-column-count: 3; /* Firefox */column-count: 3;}")),tags$style(type="text/css","#loadmessage {position: fixed;top: 0px;left: 0px;width: 100%;padding: 5px 0px 5px 0px;text-align: center;font-weight: bold;font-size: 100%;color: #000000;background-color: #CCFF66;z-index: 105;}"),".shiny-output-error { visibility: hidden; }",".shiny-output-error:before { visibility: hidden; }")),conditionalPanel(condition="$('html').hasClass('shiny-busy')",tags$div("In Progress...",id="loadmessage")),selectInput("plotType","Plot Type",choices = c("Scatter Plot","Distribution Plot")),uiOutput("gene"),uiOutput("group"),),mainPanel( plotly::plotlyOutput("out.plot") ) ) ) shinyApp(ui = ui,server = server) 和“年龄” Distribution Plot,则将用Plot TypeGroup生成图形。作为ggplot2对象时,这些数字如下所示:

P0734R0 Concepts

但是,随着ggpmisc对象(我想象ggplot2部分使用plotly的{​​{1}}函数从plotly::renderPlotly对象转换),它变成:

enter image description here

如您所见,底部的P值丢失了,图例为“行为异常”。

首选解决方案是,如果对象是ggplot2对象,请使用plotly函数;如果对象是ggplotly,请使用plotly::renderPlotly,但是我不建议使用不知道如何实现(我认为要解决和更正plotly对象转换为render对象时所做的修改)。

有什么主意吗?

解决方法

我认为最简单的解决方案是定义2个输出,一个位于plotly图前,另一个用于ggplot图,并使用shinyjs根据输入:

set.seed(1)

meta.df <- data.frame(cell = c(paste0("c_",1:1000,"_1w"),paste0("c_","_2w"),"_3w")),cluster = c(sample(c("cl1","cl2","cl3"),1000,replace=T)),age = c(rep(1,1000),rep(2,rep(3,1000)),x = rnorm(3000),y = rnorm(3000))

expression.mat <- cbind(matrix(rnorm(20*1000,1,1),nrow=20,ncol=1000,dimnames=list(paste0("g",1:20),meta.df$cell[1:1000])),matrix(rnorm(20*1000,2,meta.df$cell[1001:2000])),3,meta.df$cell[2001:3000])))

library(shiny)
library(dplyr)
library(ggplot2)
library(ggpmisc)
library(shinyjs)

server <- function(input,output,session)
{
  output$gene <- renderUI({
    selectInput("gene","Select Gene to Display",choices = rownames(expression.mat))
  })
  
  output$group <- renderUI({
    if(input$plotType == "Distribution Plot"){
      selectInput("group","Select Group",choices = c("cluster","age"))
    }
  })
  
  scatter.plot <- reactive({
    scatter.plot <- NULL
    if(!is.null(input$gene)){
      gene.idx <- which(rownames(expression.mat) == input$gene)
      plot.df <- suppressWarnings(meta.df %>% dplyr::left_join(data.frame(cell=colnames(expression.mat),value=expression.mat[gene.idx,]),by=c("cell"="cell")))
      scatter.plot <- suppressWarnings(plotly::plot_ly(marker=list(size=3),type='scatter',mode="markers",color=plot.df$value,x=plot.df$x,y=plot.df$y,showlegend=F,colors=colorRamp(c("lightgray","darkred"))) %>%
                                         plotly::layout(title=input$gene,xaxis=list(zeroline=F,showticklabels=F,showgrid=F),yaxis=list(zeroline=F,showgrid=F)) %>%
                                         plotly::colorbar(limits=c(min(plot.df$value,na.rm=T),max(plot.df$value,na.rm=T)),len=0.4,title="Scaled Expression"))
    }
    return(scatter.plot)
  })
  
  distribution.plot <- reactive({
    distribution.plot <- NULL
    if(!is.null(input$gene) & !is.null(input$group)){
      gene.idx <- which(rownames(expression.mat) == input$gene)
      plot.df <- suppressWarnings(meta.df %>% dplyr::left_join(data.frame(cell=colnames(expression.mat),by=c("cell"="cell")))
      if(input$group == "cluster"){
        distribution.plot <- suppressWarnings(plotly::plot_ly(x=plot.df$cluster,y=plot.df$value,split=plot.df$cluster,type='violin',box=list(visible=T),points=T,color=plot.df$cluster,showlegend=F) %>%
                                                plotly::layout(title=input$gene,xaxis=list(title=input$group,zeroline=F),yaxis=list(title="Scaled Expression",zeroline=F)))
      } else{
        plot.df <- plot.df %>% dplyr::mutate(time=age) %>% dplyr::arrange(time)
        plot.df$age <- factor(plot.df$age,levels=unique(plot.df$age))
        distribution.plot <- suppressWarnings(ggplot(plot.df,aes(x=time,y=value)) +
                                                geom_violin(aes(fill=age,color=age),alpha=0.3) +
                                                geom_boxplot(width=0.1,aes(color=age),fill=NA) +
                                                geom_smooth(mapping=aes(x=time,y=value,group=cluster),color="black",method='lm',size=1,se=T) +
                                                stat_poly_eq(mapping=aes(x=time,group=cluster,label=stat(p.value.label)),formula=y~x,parse=T,npcx="center",npcy="bottom") +
                                                scale_x_discrete(name=NULL,labels=levels(plot.df$cluster),breaks=unique(plot.df$time)) +
                                                facet_wrap(~cluster) + theme_minimal() + ylab(paste0("#",input$gene," Scaled Expressioh"))+theme(legend.title=element_blank()))
      }
    }
    return(distribution.plot)
  })
  
  output$out.plot_plotly <- plotly::renderPlotly({
    if(input$plotType == "Scatter Plot"){
      scatter.plot()
    } else {
      req(input$group)
      if (input$plotType == "Distribution Plot" && input$group != "age"){
        distribution.plot()
      }
    }
  })
  
  output$out.plot_plot <- renderPlot({
    req(input$group)
    if (input$plotType == "Distribution Plot" && input$group == "age") {
      distribution.plot()
    }
  })
  
  observeEvent(c(input$group,input$plotType),{
    req(input$group)
    if (input$group == "age" && input$plotType == "Distribution Plot") {
      hide("out.plot_plotly")
      show("out.plot_plot")
    } else {
      hide("out.plot_plot")
      show("out.plot_plotly")
    }
  })
}


ui <- fluidPage(
  titlePanel("Explorer"),useShinyjs(),sidebarLayout(
    sidebarPanel(
      tags$head(
        tags$style(HTML(".multicol {-webkit-column-count: 3; /* Chrome,Safari,Opera */-moz-column-count: 3; /* Firefox */column-count: 3;}")),tags$style(type="text/css","#loadmessage {position: fixed;top: 0px;left: 0px;width: 100%;padding: 5px 0px 5px 0px;text-align: center;font-weight: bold;font-size: 100%;color: #000000;background-color: #CCFF66;z-index: 105;}"),".shiny-output-error { visibility: hidden; }",".shiny-output-error:before { visibility: hidden; }")),conditionalPanel(condition="$('html').hasClass('shiny-busy')",tags$div("In Progress...",id="loadmessage")),selectInput("plotType","Plot Type",choices = c("Scatter Plot","Distribution Plot")),uiOutput("gene"),uiOutput("group"),),mainPanel(
      plotly::plotlyOutput("out.plot_plotly"),plotOutput("out.plot_plot")
    )
  )
)

shinyApp(ui = ui,server = server)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-