I have been creating ternary plots in R Markdown using the package ggtern. I am using R version 3.2.2 (2015-08-14) -- "Fire Safety" on Platform: x86_64-w64-mingw32/x64 (64-bit). I am working within R Studio Version 0.99.489.
I want to switch from printing each plot individually to using an embedded reactive script (inputSelect and renderPlot functions). However, using ggtern within renderPlot I get an error that the dataframe I am calling cannot be found. I've done a number of tests... (1) I can call the same dataframe to renderTable, (2) I can call the same dataframe to renderPlot with base plot function (just X & Y data, ignoring Z), but ggplot gives the same "object 'yourdata' cannot be found".
I've tried switching out of R Markdown to just write (and then call) a separate Shiny app, but that gives similar errors.
Can anyone explain what is going on and suggest a solution? I have a lot of these to make and my short-term fix is to run some code that loops ggtern to print the 100+ plots to png files and then use a reactive script to select and call the images. But this obviously is less than ideal! I could also try using the ternary plot options in packages compositions or robCompositions - but would prefer plotting with ggtern, if possible.
Below are the data and reactive code chunks from my R Markdown document. I've also published the entire document (https://kdvdecisionanalysis.shinyapps.io/WhyCantPlot) where you can see the various tests that work and don't work. Thanks!
```{r data.import}
# Here is a very small example of input data
triadR <- data.frame(NarrID = rep(1:5, 2), Var = c(rep("Important",5),rep("Law", 5)), X = c(14.15406, 58.15887, 11.79224, 53.37626, 24.08851, 17.53618, 21.94300, 8.92137, 49.28843, 58.15012), Y = c(74.24623, 24.49748, 18.96985, 24.49748, 52.63819, 69.22111, 58.66835, 32.53769, 33.54272, 14.94975), Z = c(11.59971, 17.34365, 69.23792, 22.12626, 23.27329, 13.24271, 19.38865, 58.54094, 17.16886, 26.90012), Ax = rep(0.5,10), Ay = rep(0.5, 10), DNA = rep(NA, 10))
triadR[3,3:5] = NA
triadQ <- data.frame(Var=c("Important", "Law"), Triad=c("People acted according to", "Justice was achieved through"), X = c("Intuition", "Reconciliation"), Y=c("Logic", "Revenge"), Z=c("Values", "Deterence"), Project=c(1,1))
triadQ
triadR
```
This is the plot that I want to make. The ggtern commands generate the correct plot outside of a Shiny renderPlot command.
```{r ggtern, echo=TRUE, fig.width=4}
inputPanel(
selectInput("Triad", "Which triad would you like to view?", levels(unique(triadQ$Triad)))
)
renderPlot({
library(ggtern)
varname <- as.character(triadQ[which(triadQ$Triad==input$Triad),triadQ$Var]$Var)
data_nas <- data.frame(triadR[which(triadR$Var==varname),])
ggtern(data = plotdata, aes(plotdata$X, plotdata$Y, plotdata$Z)) +
geom_density_tern(n = 200, aes(fill = ..level.., alpha = ..level..)) +
geom_point() +
theme_bw() +
labs(x="Stable",y="Emergent",z="Unstable",title="Fit Together") +
scale_fill_gradient(low = "blue",high = "red") +
guides(color = "none", fill = "none", alpha = "none")
})
Related
I have an issue with knitr and ggplot2 in Latex. I am trying to create a dynamic document with knitr. All my plots are in ggplot2. Hear me out:
I created the Latex document
I opened it in R Studio and saved the TEX file as RNW file. Global and Project options: knitr.
I pasted the R script there like:
<<echo=FALSE>>=
knitr::opts_chunk$set(fig.path='graphs/',
echo=FALSE, warning=FALSE, message=FALSE)
#
<<>>=
library(ggplot2)
library(tidyverse)
#
<<plot1>>=
my_data1 <- read.csv(file.choose(), header=TRUE, sep=",")
plot1 <- ggplot(data=my_data1, aes(x = pos , y = sum)) +
geom_line(colour = 'black', size = 1) +
scale_y_continuous(trans = 'log10', limits = c(1,100)) +
theme_classic() +
labs (x = 'axis_name1', y = 'axis_name2') +
coord_cartesian(xlim = c(1219890,1220102)) +
#
Everything is going well, except the graph does not show when I press 'Compile PDF' or in the graphs directory. However when I select only the R code and run it everything is fine(as long as I add print()). I managed to use TikZ which works just fine but without creating a dynamic document. I thought it was possible to output the plot directly in the PDF document but for some reason ggplot2 does not work. Is there something that I am missing?
Thank you.
I started using the lattice graphic package but I stumbled into a problem. I hope somebody can help me out.
I want to plot a histogram using the corresponding function.
Here is the file foo.r:
library("lattice")
data <- data.frame(c(1:2),c(2:3))
colnames(data) <- c("RT", "Type")
pdf("/tmp/baz.pdf")
histogram( ~ RT | factor(Type), data = data)
dev.off()
When I run this code using R --vanilla < foo.r it works all fine.
However, if I use a second file bar.r with
source("bar")
and run R --vanilla < bar.r the code produces an erroneous pdf file.
Now I found out that source("bar", echo=TRUE) solves the problem. What is going on here? Is this a bug or am I missing something?
I'm using R version 2.13.1 (2011-07-08) with lattice_0.19-30
It is in the FAQ for R -- you need print() around the lattice function you call:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such as xyplot() create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). The print() method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but in source() or
inside your own functions you will need an explicit print() statement.
Example of the case
visualise.r
calls plot2this.r
calls ggplot2 and returns p object
Here the fix in the function plot2this.r from return(p) to return(print(p)).
Initial plot2this.r
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(p)
Fix
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(print(p))
Output now: expected output with the wanted plot.
I started using the lattice graphic package but I stumbled into a problem. I hope somebody can help me out.
I want to plot a histogram using the corresponding function.
Here is the file foo.r:
library("lattice")
data <- data.frame(c(1:2),c(2:3))
colnames(data) <- c("RT", "Type")
pdf("/tmp/baz.pdf")
histogram( ~ RT | factor(Type), data = data)
dev.off()
When I run this code using R --vanilla < foo.r it works all fine.
However, if I use a second file bar.r with
source("bar")
and run R --vanilla < bar.r the code produces an erroneous pdf file.
Now I found out that source("bar", echo=TRUE) solves the problem. What is going on here? Is this a bug or am I missing something?
I'm using R version 2.13.1 (2011-07-08) with lattice_0.19-30
It is in the FAQ for R -- you need print() around the lattice function you call:
7.22 Why do lattice/trellis graphics not work?
The most likely reason is that you forgot to tell R to display the
graph. Lattice functions such as xyplot() create a graph object, but
do not display it (the same is true of ggplot2 graphics, and Trellis
graphics in S-Plus). The print() method for the graph object produces
the actual display. When you use these functions interactively at the
command line, the result is automatically printed, but in source() or
inside your own functions you will need an explicit print() statement.
Example of the case
visualise.r
calls plot2this.r
calls ggplot2 and returns p object
Here the fix in the function plot2this.r from return(p) to return(print(p)).
Initial plot2this.r
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(p)
Fix
p <- ggplot(dat.m, aes(x = Vars, y = value, fill=variable))
return(print(p))
Output now: expected output with the wanted plot.
I would like to display a plotly plot object in a standalone window that behaves similarly to the window that pops up using the base R plot() function.
Using a basic example from the plotly website:
library(ggplot2)
library(plotly)
d <- diamonds[sample(nrow(diamonds), 1000), ]
p <- ggplot(data = d, aes(x = carat, y = price)) +
geom_point(aes(text = paste("Clarity:", clarity))) +
geom_smooth(aes(colour = cut, fill = cut)) + facet_wrap(~ cut)
p2 <- ggplotly(p)
The p2 object is an htmlwidget object and I get some control over its display using the sizingPolicy element as described here. However, I can't find anything that allows me to set the viewer/browser to something other than my current browser (as a new tab) or within RStudio.
Ideally, I'd like to avoid applications outside of R packages to launch a separate window from within R. However, I would also be happy with figuring out how to granularly control browser output to display p2 as a new window in kiosk or app mode (see the answers to this question for some examples of kiosk/app mode).
Edit: Although I mentioned RStudio when discussing some of the options that I was able to find, I am talking about using R from a simple console. That said, granular display options should hopefully be independent of the user interface.
I have a working solution, but I'll be happy to change the accepted answer if someone has anything better.
I defined a print function that can be used to launch a custom browser command for an htmlwidget object. In this case, I used chromium-browser -app=..., but the overall approach should be general.
print_app <- function(widget) {
# Generate random file name
temp <- paste(tempfile('plotly'), 'html', sep = '.')
# Save. Note, leaving selfcontained=TRUE created files that froze my browser
htmlwidgets::saveWidget(widget, temp, selfcontained = FALSE)
# Launch with desired application
system(sprintf("chromium-browser -app=file://%s", temp))
# Return file name if it's needed for any other purpose
temp
}
Combining with the previous example:
library(ggplot2)
library(plotly)
d <- diamonds[sample(nrow(diamonds), 1000), ]
p <- ggplot(data = d, aes(x = carat, y = price)) +
geom_point(aes(text = paste("Clarity:", clarity))) +
geom_smooth(aes(colour = cut, fill = cut)) + facet_wrap(~ cut)
p2 <- ggplotly(p)
print_app(p2)
It seems like htmlwidgets normally uses the html_print function from htmltools, which in turn selects the browser to use via getOption("viewer", utils::browseURL), which bakes in a lot of the browser selection options -- making it challenging to change.
The idea for saving the html file locally came from this plotly issue: saving plotly plots locally?.
If you are using MacOS, change this line in #ssokolen's answer
# Launch with desired application
system(sprintf("chromium-browser -app=file://%s", temp))
to
system(sprintf("open -a 'google chrome' /%s", temp))
Works in zsh in MacOs Catalina with the Intellij R plugin.
I am trying to add a correlation heatmap using ggplot to an HTML R markdown report. The sample code below works in my R Studio console but breaks when I knit HTML.
The error is vague and I am not sure what the best approach is to debug.
HTML knit error message:
Error in exists(name, envir = env, mode = mode) : argument "env" is
missing, with no default
Calls: ... ggplot_build -> scales_add_missing ->
find_global -> exists
Does anyone else get the same error when they try to knit the code below?
library(reshape2)
library(psych)
library(ggplot2)
set.seed(1)
a <- sample(c(0,1),20,rep=T)
b <- sample(50:100,20,rep=T)
df <- cbind(a,b)
corr.out <- corr.test(df, adjust = "none", use="complete")
# the stats heatmap function displays fine in R Markdown
heatmap(corr.out$r)
# this ggplot attempt breaks for some reason
dfm <- melt(corr.out$r)
ggplot(data=dfm, aes(dfm$X1, dfm$X2, fill=dfm$value)) +
geom_tile() +
xlab(NULL) + ylab(NULL) + ggtitle("Correlation coefficients Heatmap") +
theme(legend.position="bottom")
# i call "dfm$X1" in aes() because i get the error "Object X1 not found"
# when i only specify "X1"
R version 3.1.1 (2014-07-10)
Platform: x86_64-apple-darwin13.1.0