Tuesday, March 5, 2019

r - How to retain plot layout characteristics when using ggplot in Shiny?

When making a straightforward ggplot, the canvas size will extend so that the height of the plot is appropriate, allowing for some spacing between variables. For example, if I have 10 variables I need to show on one plot, everything is plotted nicely:



enter image description here




Time to do some Shiny! Let's see if I can embed this plot in a tabPanel.



Here we go:
enter image description here



Looks great, but now my horizontal segments all look cramped together like a pack of hotdogs. There is no whitespace between the horizontal geom_segments.



This issue constantly plagues me.



I feel like ggplot has a brain of it's own, when it comes to canvas sizes, which is fine, but I can't pry the skull off to appropriately control how it will plot itself.




To quote Forrest R. Stevens,
"...the key to getting consistent canvas and all other dimensions is to control the graphic output device directly."



I totally agree with him and used his excellent advice here, yet there is no way to control this since we are using Shiny.



Next I attempted to play with the values in



           p <- p + theme(plot.margin=unit(c(0,0,0,0), "cm")
p <- p + panel.margin=unit(c(0,0,0,0), "cm"))



but alas it did no good; it merely created margins and further crunched things together, which makes perfect sense.



My question is this -- how can I change my ggplot so that it appears in Shiny with proper spacing?



Good looking ggplot, not in Shiny:



  library("shiny")
library("ggplot2")


DF_for_plotting <- structure(list(col1 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), col2 = c(100,
100, 61.9433678425096, 10.7823906941804, 4.18175346165306, 3.24251454697229,
6.68573373055455, 14.945119260922, 18.9296271776082, 11.0742379220636
), col3 = c(100, 100, 100, 12.8418470680653, 5.31239161296286,
4.42025167250118, 10.699998838647, 27.5067118056336, 20.6360723198699,
13.1476876837599), col4 = c(100, 100, 100, 100, 100, 100, 100,
100, 100, 100)), .Names = c("col1", "col2", "col3", "col4"), row.names = c("one",
"two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten"), class = "data.frame")


hex=c("#CC0000", "#90BD31", "#178CCB")
textsize <- c(9)
number_of_variables <- 5

p <- ggplot()
p <- p + scale_y_discrete(breaks = seq(10), labels = c("one", "two", "three", "four", "five"))

breaks=c(0, 25, 50, 75, 100)
break_labels=c("0%", "25%", "50%", "75%", "100%")


p <- p + scale_x_continuous(breaks = breaks, labels=break_labels, name=percent_correct)

### inner loop
for (varnum in seq(1:number_of_variables)){ #<-- we are already in the Tab. Now we need to make all three segments for all three variables for this tab

p <- p + geom_segment(data=DF_for_plotting, aes_q(x=DF_for_plotting$col1[varnum], xend=DF_for_plotting$col2[varnum]-0.001, y=varnum, yend=varnum, colour='impaired'), size=textsize*2.5) +
geom_segment(data=DF_for_plotting, aes_q(x=DF_for_plotting$col2[varnum], xend=DF_for_plotting$col3[varnum]-0.001, y=varnum, yend=varnum, colour='normal'), size=textsize*2.5) +
geom_segment(data=DF_for_plotting, aes_q(x=DF_for_plotting$col3[varnum], xend=DF_for_plotting$col4[varnum]-0.001, y=varnum, yend=varnum, colour='optimal'), size=textsize*2.5)
p <- p + scale_color_manual(values=c(impaired=hex[1], normal=hex[2], optimal=hex[3], white='#ffffff'), name="Function Key")

}
p


UI.R



shinyUI(fluidPage(theme='test.css',

fluidRow(
column(2,

fluidRow(
h3("Select Customer:"),
wellPanel(class="info", numericInput(inputId="num", label="Select ID:", value=NaN),
if(show_age_slider=='Yes'){textOutput("")},
if(show_edu_slider=='Yes'){textOutput("")},
if(show_gender_buttons=='Yes'){textOutput("")}
))),

#do.call will call the navbarPage function with the arguments in the tabs list
shinyUI(fluidRow(

column(12,
"",
do.call(navbarPage,tabs)
))))))


SERVER.R



library("shiny")
library("ggplot2")


DF_for_plotting <- structure(list(col1 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), col2 = c(100,
100, 61.9433678425096, 10.7823906941804, 4.18175346165306, 3.24251454697229,
6.68573373055455, 14.945119260922, 18.9296271776082, 11.0742379220636
), col3 = c(100, 100, 100, 12.8418470680653, 5.31239161296286,
4.42025167250118, 10.699998838647, 27.5067118056336, 20.6360723198699,
13.1476876837599), col4 = c(100, 100, 100, 100, 100, 100, 100,
100, 100, 100)), .Names = c("col1", "col2", "col3", "col4"), row.names = c("one",
"two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten"), class = "data.frame")



hex=c("#CC0000", "#90BD31", "#178CCB")
textsize=c(8)

############## shiny server starts here: #######################################################################
shinyServer(function(input, output) {

# begin the observe() block
observe(



lapply(seq(1:number_of_tabs),function(i) output[[paste0("plot",i)]] <- renderPlot({ #<-- lapply will fill up each tab and create one ggplot
plotindex <<- 0
list_of_ggplots <<- list() #although we only have one tab, we could easily extend to having multiple tabs
p <- ggplot()

breaks=c(0, 25, 50, 75, 100, 115, 130)
break_labels=c("0%", "25%", "50%", "75%", "100%")


number_of_variables <- 10

### inner loop
for (varnum in seq(1:number_of_variables)){ #<-- We need to make all three segments for all three variables for this tab

p <- p + scale_y_discrete(breaks = seq(10), labels = c("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"))



p <- p + geom_segment(data=DF_for_plotting, aes_q(x=DF_for_plotting$col1[varnum], xend=DF_for_plotting$col2[varnum]-0.001, y=varnum, yend=varnum, colour='impaired'), size=textsize*2.5) +

geom_segment(data=DF_for_plotting, aes_q(x=DF_for_plotting$col2[varnum], xend=DF_for_plotting$col3[varnum]-0.001, y=varnum, yend=varnum, colour='normal'), size=textsize*2.5) +
geom_segment(data=DF_for_plotting, aes_q(x=DF_for_plotting$col3[varnum], xend=DF_for_plotting$col4[varnum]-0.001, y=varnum, yend=varnum, colour='optimal'), size=textsize*2.5)
p <- p + scale_color_manual(values=c(impaired=hex[1], normal=hex[2], optimal=hex[3], white='#ffffff'), name="Function Key")
# p <- p + theme(plot.margin=unit(c(0,0,0,0), "cm"))
# p <- p + theme(panel.margin=unit(c(0,0,0,0), "cm"))

list_of_ggplots[["to_UI"]] <<- p # this is strange but true; apparently any arbitrary key works for inserting the plot into the list_of_ggplots
}
print(list_of_ggplots) #<-- to send out to UI
})

)


) #<-- end of observe function
} #<-- end of brace in shinyserver function
) #<-- end the shinyserver function

No comments:

Post a Comment

plot explanation - Why did Peaches&#39; mom hang on the tree? - Movies &amp; TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...