Flexdashboard not able to render ggplotly and ggplot object on same markdown - ggplot2

I have a basic reproducible example here that I think might just be a package limitation. I was wondering if I am just doing something wrong? They both plot fine separately but when combined in the same markdown make the dashboard unable to correctly render.
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: rows
source_code: embed
runtime: shiny
---
```{r setup, include=FALSE}
library(tidyverse)
library(plotly)
library(albersusa)
state_sf <- usa_sf("aeqd")
state_dat <- data.frame(state = c("Washington", "Wyoming","Texas","California"), pct = c(0.3,0.5,0.8,0.1))
state_map <- state_sf %>%
left_join(state_dat, by = c("name" = "state"))
```
Test
=====================================
Sidebar {.sidebar data-width=200}
-------------------------------------
Testing
Row
-----------------------------------------------------------------------
###Plotly
```{r graph 1, fig.height=4, fig.width=6}
#Symptoms by state last week===================================================
ggplotly(
ggplot(data = state_map) +
geom_sf(aes(fill=pct))
)
```
###Bar
```{r graph 2, fig.height=4, fig.width=3}
ggplot(data=state_dat) +
geom_col(aes(state,pct,fill=pct))
```

If you are using runtime: shiny you need to use the proper type of Shiny's renderX() functions for each type of plot object to display properly. I don't know why only one plot chunk (w/o renderX()) works, but two breaks it.
### Plotly
```{r graph_1, fig.height=4, fig.width=3}
#Symptoms by state last week
renderPlotly({
ggplotly(
ggplot(data = state_map) +
geom_sf(aes(fill=pct))
)
})
```
### Bar
```{r graph_2, fig.height=4, fig.width=3}
renderPlot({
ggplot(data=state_dat) +
geom_col(aes(state,pct,fill=pct))
})
```

Related

! Package pdftex.def Error - when knitting to PDF

I am able to knit to PDF for the example below:
---
title: "R Notebook"
output:
pdf_document: default
html_notebook: default
html_document:
df_print: paged
---
Table 1 example:
```{r, warning=FALSE, message=FALSE, echo=FALSE, include=FALSE, fig.pos="H"}
library(magrittr)
library(tidyverse)
library(kableExtra)
library(readxl)
library(modelsummary)
library(scales)
tmp <- mtcars
# create a list with individual variables
# remove missing and rescale
tmp_list <- lapply(tmp, na.omit)
tmp_list <- lapply(tmp_list, scale)
# create a table with `datasummary`
# add a histogram with column_spec and spec_hist
# add a boxplot with colun_spec and spec_box
emptycol = function(x) " "
final_4_table <- datasummary(mpg + cyl + disp + hp + drat + wt + qsec + vs + am + gear + carb ~ N + Mean + SD + Heading("Boxplot") * emptycol + Heading("Histogram") * emptycol, data = tmp) %>%
column_spec(column = 5, image = spec_boxplot(tmp_list)) %>%
column_spec(column = 6, image = spec_hist(tmp_list))
```
```{r finaltable, echo=FALSE}
final_4_table
```
However, I cannot knit to PDF my own code which involves more variables. My R Markdown starts by reading my excel file and then it is pretty much the same as example above:
---
title: "table1"
output:
pdf_document: default
html_document:
df_print: paged
---
Table 1
```{r prep-tableone, message=FALSE, warning=FALSE, echo=FALSE, include=FALSE, fig.pos="H"}
library(magrittr)
library(tidyverse)
library(kableExtra)
library(readxl)
library(modelsummary)
library(scales)
### set directory
setwd("/etcetc1")
## read dataset
my_dataset <- read_excel("my_dataset.xlsx")
my_dataset <- as.data.frame(my_dataset)
...
I can run this code in R script; it works just fine. I can also knit this code to HTML just fine. When trying to knit to PDF I get the following error:
output file: table1test.knit.md
! Package pdftex.def Error: File `table1test_files/figure-latex//boxplot_65c214bae9bb.pdf' not found: using draft setting.
Error: LaTeX failed to compile table1test.tex. See https://yihui.org/tinytex/r/#debugging for debugging tips. See table1test.log for more info.
In addition: Warning messages:
1: package 'ggplot2' was built under R version 4.1.1
2: package 'tibble' was built under R version 4.1.1
3: package 'tidyr' was built under R version 4.1.1
4: In in_dir(input_dir(), evaluate(code, envir = env, new_device = FALSE, :
You changed the working directory to /etcetc1 (probably via setwd()). It will be restored to /etcetc2. See the Note section in ?knitr::knit
Execution halted
Am I missing any packages? Do you know what might be happening?
I use TeXShop for LaTeX.

kable unable to output unicode character in pdf_book (bookdown)

I am trying to use the checkmark unicode character (\u2713) in a table rendered by kable in a bookdown project. A MWE consists in the following 2 files (index.Rmd, preamble.tex) part of the generated minimal bookdown project.
index.Rmd
---
title: "A Minimal Book Example"
subtitle: "subtitle"
lang: fr
author: "Yihui Xie"
date: "`r Sys.Date()`"
site: bookdown::bookdown_site
documentclass: book
mainfont: Arial
mathfont: Arial
bibliography: [book.bib, packages.bib]
biblio-style: apalike
link-citations: yes
subparagraph: yes
description: "This is a minimal example of using the bookdown package to write a book. The output format for this example is bookdown::gitbook."
---
```{r setup, include=FALSE}
# Set locale to french for month and day names (calendar plots)
Sys.setlocale(locale = 'French')
# Load all needed libraries
if(!require('pacman'))install.packages('pacman')
pacman::p_load(kableExtra)
```
(ref:O3) O~3~
# Prerequisites
✓
```{r stations-polluants, echo=FALSE}
stations_polluants_table <- data.frame(
stations = c("41B001", "41B004", "41B011", "41MEU1", "41N043", "41R001", "41R002", "41R012", "41WOL1", "Total / polluant"),
O3 = c("", rep("✓", 5), "", rep("\u2713", 2), "7")
)
kable(stations_polluants_table, col.names = c("Station", "(ref:O3)"), booktabs = T, align = "c", caption = "Caption text") %>%
row_spec(0, bold = T) %>%
row_spec(10, bold = T) %>%
collapse_rows(columns = 1, latex_hline = "major", valign = "top")
```
```{r include=FALSE}
# automatically create a bib database for R packages
knitr::write_bib(c(
.packages(), 'bookdown', 'knitr', 'rmarkdown'
), 'packages.bib')
```
preamble.tex
\usepackage{booktabs}
\newfontfamily{\unicodefont}{Arial Unicode MS}
\usepackage{newunicodechar}
\newunicodechar{✓}{{\unicodefont{✓}}}
By compiling in PDF with rmarkdown::render_site(output_format = 'bookdown::pdf_book', encoding = 'UTF-8') one can notice that ✓ is correctly rendered in the text, while it is replaced by <U+2713> in the generated table. I also tried to use \u2713 in the table without more success.
What am I doing wrong ? Please note that, even if the prefered output is PDF, I would also like to compile as gitbook (so Rmd files need to stay independent from the output format).
Many thanks.
After having a moment of clarity, the solution simply lies in using text references in bookdown, i.e. (ref:check) ✓ and use the reference within the table.
index.Rmd
```{r setup, include=FALSE}
# Set locale to french for month and day names (calendar plots)
Sys.setlocale(locale = 'French')
# Load all needed libraries
if(!require('pacman'))install.packages('pacman')
pacman::p_load(kableExtra)
```
(ref:O3) O~3~
# Prerequisites
✓
(ref:check) ✓
```{r stations-polluants, echo=FALSE}
stations_polluants_table <- data.frame(
stations = c("41B001", "41B004", "41B011", "41MEU1", "41N043", "41R001", "41R002", "41R012", "41WOL1", "Total / polluant"),
O3 = c("", rep("(ref:check)", 5), "", rep("(ref:check)", 2), "7")
)
kable(stations_polluants_table, col.names = c("Station", "(ref:O3)"), booktabs = T, align = "c", caption = "Caption text") %>%
row_spec(0, bold = T) %>%
row_spec(10, bold = T) %>%
collapse_rows(columns = 1, latex_hline = "major", valign = "top")
```
```{r include=FALSE}
# automatically create a bib database for R packages
knitr::write_bib(c(
.packages(), 'bookdown', 'knitr', 'rmarkdown'
), 'packages.bib')
```

Can we bind three plots using rbind_gtable in shiny dashboard to download all the plots together?

Trouble combining multiple shiny plots and downloading through a single click.
Code below is from the answer here: Solution
I tried this solution. It works fine for two plots but as soon as I add another plot it only returns the graph information but not the graph themselves.
Combining two plots works fine.
I also tried other solutions but both of the solutions when implemented returns a text file instead of pdf or pdf file that is corrupted.
Solution1
Solution2
Any suggestion would be really appreciated. Thank you!
Code
library(ggplot2)
ui <- shinyUI(fluidPage(
titlePanel("Test app"),
fluidRow(
column(4,
wellPanel(
downloadButton('download',label="Download plot as png")
)
),
column(8,
plotOutput("plot")
)
)
))
server <- function(input,output) {
plotting<- reactive({
data1=data.frame(x=rnorm(50),y=rnorm(50))
data2=data.frame(x=rexp(50),y=rexp(50))
data3=data.frame(x=rexp(50),y=rexp(50))
plot1=ggplot(data1,aes(x,y))+geom_point()
plot2=ggplot(data2,aes(x,y))+geom_point()
plot3=ggplot(data3,aes(x,y))+geom_point()
gb1=ggplot_build(plot1)
gb2=ggplot_build(plot2)
gb3=ggplot_build(plot3)
gA <- ggplot_gtable(gb1)
gB <- ggplot_gtable(gb2)
gC <- ggplot_gtable(gb3)
both <- gtable:::rbind_gtable(gA, gB, "last")
all <- gtable:::rbind_gtable(both, gC, "last")
return(all)
})
output$plot <- renderPlot({
grid.newpage()
grid.draw(plotting())
})
output$download <- downloadHandler(
filename <- "shinytestplot.png",
# Changes:
content <- function(file){ ## file = NULL --> file
png(file) # filename --> file
grid.newpage()
grid.draw(plotting())
dev.off()
}
)
}
shinyApp(server=server,ui=ui)
Your example works just fine for me. However, I'd recommend against rbinding plots. Use the patchwork package instead.
library(ggplot2)
library(shiny)
library(patchwork)
ui <- shinyUI(fluidPage(
titlePanel("Test app"),
fluidRow(
column(4,
wellPanel(
downloadButton('download',label="Download plot as png")
)
),
column(8,
plotOutput("plot")
)
)
))
server <- function(input,output) {
plotting<- reactive({
data1=data.frame(x=rnorm(50),y=rnorm(50))
data2=data.frame(x=rexp(50),y=rexp(50))
data3=data.frame(x=rexp(50),y=rexp(50))
plot1=ggplot(data1,aes(x,y))+geom_point()
plot2=ggplot(data2,aes(x,y))+geom_point()
plot3=ggplot(data3,aes(x,y))+geom_point()
# stack the plots on top of one another with patchwork
plot1 / plot2 / plot3
})
output$plot <- renderPlot({
print(plotting())
})
output$download <- downloadHandler(
filename <- "shinytestplot.png",
# Changes:
content <- function(file){
ggsave(file, plotting())
}
)
}
shinyApp(server=server,ui=ui)

Issue when trying to plot geom_tile using ggplotly

I would like to plot a ggplot2 image using ggplotly
What I am trying to do is to initially plot rectangles of grey fill without any aesthetic mapping, and then in a second step to plot tiles and change colors based on aesthetics. My code is working when I use ggplot but crashes when I try to use ggplotly to transform my graph into interactive
Here is a sample code
library(ggplot2)
library(data.table)
library(plotly)
library(dplyr)
x = rep(c("1", "2", "3"), 3)
y = rep(c("K", "B","A"), each=3)
z = sample(c(NA,"A","L"), 9,replace = TRUE)
df <- data.table(x,y,z)
p<-ggplot(df)+
geom_tile(aes(x=x,y=y),width=0.9,height=0.9,fill="grey")
p<-p+geom_tile(data=filter(df,z=="A"),aes(x=x,y=y,fill=z),width=0.9,height=0.9)
p
But when I type this
ggplotly(p)
I get the following error
Error in [.data.frame(g, , c("fill_plotlyDomain", "fill")) :
undefined columns selected
The versions I use are
> packageVersion("plotly")
1 ‘4.7.1
packageVersion("ggplot2")
1 ‘2.2.1.9000’
##########Edited example for Arthur
p<-ggplot(df)+
geom_tile(aes(x=x,y=y,fill="G"),width=0.9,height=0.9)
p<- p+geom_tile(data=filter(df,z=="A"),aes(x=x,y=y,fill=z),width=0.9,height=0.9)
p<-p+ scale_fill_manual(
guide = guide_legend(title = "test",
override.aes = list(
fill =c("red","white") )
),
values = c("red","grey"),
labels=c("A",""))
p
This works
but ggplotly(p) adds the grey bar labeled G in the legend
The output of the ggplotly function is a list with the plotly class. It gets printed as Plotly graph but you can still work with it as a list. Moreover, the documentation indicates that modifying the list makes it possible to clear all or part of the legend. One only has to understand how the data is structured.
p<-ggplot(df)+
geom_tile(aes(x=x,y=y,fill=z),width=0.9,height=0.9)+
scale_fill_manual(values = c(L='grey', A='red'), na.value='grey')
p2 <- ggplotly(p)
str(p2)
The global legend is here in p2$x$layout$showlegend and setting this to false displays no legend at all.
The group-specific legend appears at each of the 9 p2$x$data elements each time in an other showlegend attribute. Only 3 of them are set to TRUE, corresponding to the 3 keys in the legend. The following loop thus clears all the undesired labels:
for(i in seq_along(p2$x$data)){
if(p2$x$data[[i]]$legendgroup!='A'){
p2$x$data[[i]]$showlegend <- FALSE
}
}
Voilà!
This works here:
ggplot(df)+
geom_tile(aes(x=x,y=y,fill=z),width=0.9,height=0.9)+
scale_fill_manual(values = c(L='grey', A='red'), na.value='grey')
ggplotly(p)
I guess your problem comes from the use of 2 different data sources, df and filter(df,z=="A"), with columns with the same name.
[Note this is not an Answer Yet]
(Putting for reference, as it is beyond the limits for comments.)
The problem is rather complicated.
I just finished debugging the code of plotly. It seems like it's occurring here.
I have opened an issue in GitHub
Here is the minimal code for the reproduction of the problem.
library(ggplot2)
set.seed(1503)
df <- data.frame(x = rep(1:3, 3),
y = rep(1:3, 3),
z = sample(c("A","B"), 9,replace = TRUE),
stringsAsFactors = F)
p1 <- ggplot(df)+
geom_tile(aes(x=x,y=y, fill="grey"), color = "black")
p2 <- ggplot(df)+
geom_tile(aes(x=x,y=y),fill="grey", color = "black")
class(plotly::ggplotly(p1))
#> [1] "plotly" "htmlwidget"
class(plotly::ggplotly(p2))
#> Error in `[.data.frame`(g, , c("fill_plotlyDomain", "fill")): undefined columns selected

ggplot plotly API mess width stack bar graph

I am using plotly library to get me HTML interactive graph, which i already generating from ggplot2, but with stacked graph, plotly doesnt work properly.
Here is my ggplot code :
if(file.exists(filename)) {
data = read.table(filename,sep=",",header=T)
} else {
g <- paste0("=== [E] Error : Couldn't Found File : ",filename)
print (g)
}
ReadChData <- data[data$Channel %in% c("R"),]
#head(ReadChData,10)
# calculate midpoints of bars (simplified using comment by #DWin)
Data <- ddply(ReadChData, .(qos_level),
transform, pos = cumsum(AvgBandwidth) - (0.5 *AvgBandwidth)
)
# library(dplyr) ## If using dplyr...
# Data <- group_by(Data,Year) %>%
# mutate(pos = cumsum(Frequency) - (0.5 * Frequency))
# plot bars and add text
g <- ggplot(Data, aes(x = qos_level, y = AvgBandwidth)) +
scale_x_continuous(breaks = x_axis_break) +
geom_bar(aes(fill = MasterID), stat="identity", width=0.2) +
scale_colour_gradientn(colours = rainbow(7)) +
geom_text(aes(label = AvgBandwidth, y = pos), size = 3) +
theme_set(theme_bw()) +
ylab("Bandwidth (GB/s)") +
xlab("QoS Level") +
ggtitle("Qos Compting Stream")
png(paste0(opt$out,"/",GraphName,".png"),width=6*ppi, height=6*ppi, res=ppi)
print (g)
library(plotly)
p <- ggplotly(g)
#libdir arugumet will be use to point to commin lib
htmlwidgets::saveWidget(as.widget(p), selfcontained=FALSE, paste0(opt$out,"/qos_competing_stream.html"))
and here is HTML output form plotly lib
http://pasteboard.co/2fHQfJwFu.jpg
Please help.
This is perhaps quite a bit late to answer. But for someone who might have the issue in future...
The geom_bar's width parameter is not recognized by ggplotly function.
Work Around :
A work around (not very good one) by using parameters colour="white", size = 1. This basically adds a white line around the bars, making an effect like white space.
You could try the following:
stat_summary(aes(fill = MasterID), geom="bar", colour="white", size = 1, fun.y = "sum", position = "stack")
Better solution :
Use bargap parameter from layout function. The code should be:
ggplotly(type='bar', ...) %>% layout(bargap = 3, autosize=T)
P.S. the code in question code is not executable, throws an error due to missing filename.