Heatmap Not Displaying on Shiny App Load

646 views
Skip to first unread message

Jeff Bruce

unread,
May 4, 2015, 3:14:48 PM5/4/15
to shiny-...@googlegroups.com
Greetings fellow Shiny useRs!

I have been working on an app to display mouse neuroanatomical data clustered by mouse strain.  I've greatly simplified the app for the purposes of explaining it here and creating a reproducible example.  Basically, all the map is is a heatmap.  The problem is, during some point when I was coding the app, the heatmap stopped showing up on the first page of the app when I'd launch it locally in my browser, and I'd have to resize the window in order for the heatmap to show up properly.  Since I'm relatively stumped, I've created what I believe to be a reproducible example with the hope that an expert can help me out:

ui.R

shinyUI(
  navbarPage
('Menu',
                         
             tabPanel
('Filter and Recluster',
                             
                      titlePanel
('Blah'),
                     
                      p
('Blah'),
                     
                      hr
(),
                     
                      fluidRow
(column(12, plotOutput(outputId = 'heatmap1', height = "800px"))),
                     
                      hr
(),
                     
                      fluidRow
(
                        column
(4, checkboxInput(inputId = 'selectAllStrains',
                                                label
= 'Select/Deselect All Strains',
                                                value
= TRUE)),
                        column
(4, checkboxInput(inputId = 'selectAllRegions',
                                                label
= 'Select/Deselect All Regions',
                                                value
= TRUE))
                     
),
                     
                      hr
(),
                     
                      fluidRow
(
                        column
(4, uiOutput('selectStrains')),
                        column
(4, uiOutput('selectRegions')),
                        column
(4, actionButton('recalculate', 'Recalculate'))
                     
)
                     
             
),
             
             
             tabPanel
('Plot Means and Effect Sizes',
                         
                      hr
()
             
)
 
)
)


server.R

jdfs = function(x) {
 
as.dist(1-cor(t(x)))  
}

shinyServer
(
 
function(input, output) {
       
   
# Page 1 dynamic control - select all brain regions
    output$selectRegions
= renderUI({
     
if (input$selectAllRegions == TRUE) {
        checkboxGroupInput
(inputId = 'regions',
                           label
= h3('Brain Regions'),
                           choices
= sort(colnames(testdatadf)),
                           selected
= colnames(testdatadf))
     
} else {
        checkboxGroupInput
(inputId = 'regions',
                           label
= h3('Brain Regions'),
                           choices
= sort(colnames(testdatadf)),
                           selected
= vector(mode="character", length=0))
     
}    
   
})
   
   
# Page 1 dynamic control - select all mouse strains
    output$selectStrains
= renderUI({
     
if (input$selectAllStrains == TRUE) {
        checkboxGroupInput
(inputId = 'strains',
                           label
= h3('Mouse Strains'),
                           choices
= sort(rownames(testdatadf)),
                           selected
= rownames(testdatadf))
     
} else {
        checkboxGroupInput
(inputId = 'strains',
                           label
= h3('Mouse Strains'),
                           choices
= sort(rownames(testdatadf)),
                           selected
= vector(mode="character", length=0))
     
}    
   
})
   
   
# Page 1 plot - heatmap for reclustering
    output$heatmap1
= renderPlot({
      input$recalculate
     
     
# isolate() prevents heatmap from regenerating every time a new strain/region is selected
      testdatadfmat
= as.matrix(testdatadf[isolate(input$strains), isolate(input$regions)])
      nr
= dim(testdatadfmat)[1]
      nc
= dim(testdatadfmat)[2]
     
     
if (dim(testdatadfmat)[1] > 1 & dim(testdatadfmat)[2] > 1) {
        heatmap
.2(x=testdatadfmat,
                  distfun
=jdfs,
                 
#hclustfun=hclust.avg,
                  col
=bluered,
                  margins
=c(20,14),
                  trace
='none',
                  cexRow
=1.5,
                  cexCol
=1.5,
                  density
.info='histogram',
                  keysize
=0.8,
                  symkey
=TRUE,
                  symbreaks
=TRUE)
     
}
   
}, height=800)
   
 
}
)

global.R


require(gplots)
require(shiny)

# simulate mousedata
testdata
= rep(x=-5:5, each=1, times=10)
testdatadf
= as.data.frame(matrix(testdata, nrow=10, ncol=10))

Please excuse the awkward indentation in these files -- I haven't found a robust tool yet to automatically indent R code (formatR unfortunately doesn't work for Shiny code as far as I know).

Basically, when you launch this app from a directory using:

runApp(appDir=<directory containing the above files>, launch.browser=TRUE)

The plot will not immediately show up on the first page, yet, if you press Recalculate or resize the window in the horizontal dimension the plot will show up.  I have determined that if I comment out the following lines in ui.R:

                      titlePanel('Blah'),
                     
                      p
('Blah'),
                     
                      hr
(),

Then the plot magically shows up again without having the manually click the Recalculate button or resize the window.  Any idea why this would be the case?

adrie...@hotmail.com

unread,
May 5, 2015, 3:54:05 AM5/5/15
to shiny-...@googlegroups.com
Hello,
When I lauchn your app, it displays that 'testdatadf' object is unfindable.

Jeff Bruce

unread,
May 5, 2015, 11:51:42 AM5/5/15
to shiny-...@googlegroups.com
Strange.  It works for me.

I've also got additional information for anyone who might be interested:
  • I've tried disabling my single browser extension and the plot still doesn't immediately show up when I launch the app in the browser.
  • Commenting out the titlePanel, p, and hr on ui.R, if I copy and paste the url for the app when it's running into a browser window, the browser window needs to be sufficiently wide for the plot to immediately show up.
  • Commenting out the titlePanel, p, and hr on ui.R, it seems like the plot more consistently immediately shows up in rekonq as opposed to firefox.

System specs: Mozilla Firefox 37.0.1, Ubuntu 12.04.4, 64-bit

Winston Chang

unread,
May 5, 2015, 11:59:19 AM5/5/15
to adrie...@hotmail.com, shiny-discuss
The problem is that the initial values of input$strains and input$regions are NULL, because they are dynamic UI.

And because you have them in isolate(), when these values do get updated, they don't cause the plot to get redrawn. (What does cause the plot to redraw when you resize is an implicit dependence on the height and width of the plotting region. More info on that at http://shiny.rstudio.com/articles/client-data.html)


If you put this code inside your renderPlot code, you'll see the NULL values:
    isolate({
      print(input$strains)
      print(input$regions)
    })


What you want is for the renderPlot() to take a dependency on input$strains and input$regions when they're NULL, and then to drop that dependency when they're not NULL.

Adding these to the renderPlot() should do the trick:
    if (is.null(isolate(input$strains)))
      validate(need(input$strains, FALSE))
    if (is.null(isolate(input$regions)))
      validate(need(input$regions, FALSE))


The validate(need()) part checks for a valid value, and exits the function if it's not valid (e.g. NULL or FALSE).

-Winston


On Tue, May 5, 2015 at 2:54 AM, <adrie...@hotmail.com> wrote:
Hello,
When I lauchn your app, it displays that 'testdatadf' object is unfindable.

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/57bdf8d1-a8e7-4e0b-b911-f6be70acb333%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Jeff Bruce

unread,
May 5, 2015, 2:13:36 PM5/5/15
to shiny-...@googlegroups.com
Thanks Winston.  Much appreciated, it works.

I'm wondering though, when will the validate(need()) part inside of the if blocks ever be FALSE and exit the function?  As far as I understand it, this condition will never happen, so can I just put input$strains and input$regions inside the if blocks, respectively, so that the dependency is created?  Or does this come down to style more than anything?

I'm also still sort of confused because even if the dependency is created conditionally when input$strains or input$regions are NULL, shouldn't an empty plot be generated since when it goes to retrieve the values in input$strains and input$regions, there are no values since input$strains and input$regions are NULL?

Joe Cheng

unread,
May 5, 2015, 5:39:07 PM5/5/15
to Jeff Bruce, shiny-...@googlegroups.com
The validate(need()) part will always trigger if those values are NULL, and that'll stop the rest of the renderPlot from executing.

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages