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.
Related
I am trying to create a scatterplot in rstudio with my data. I am new to rstudio and having a lot of time understanding. The code I have found says plot().
This is what I used: plot(pa2_wti2$ï..Approving, pa2_wti2$ï..Price)
Even when I tried a single it didn't give me a scatter plot. I have tried ggplot but it says it does not find what I have put as the x.
I have tried:
ggplot(pa2_wti2) +
geom_point(aes(x = Price, y= Approving))
ggplot(pa2_wti2) +
geom_point(aes(x = ï..Price, y= ï..Approving))
Any help is welcomed. Thanks!
Here is some additional information:
wti2 <- read.csv("C:/Users/thomp/OneDrive/Desktop/FQM/Data Project 2/WTI Price Only Take 2.csv")
summary(wti2)
table(wti2)
sd(wti2$ï..Price)
wti2_prices2 = rnorm(wti2$ï..Price, mean=43.92, sd=28.1762)
pa2 <- read.csv("C:/Users/thomp/OneDrive/Desktop/FQM/Data Project 2/PA Approval Only Take 2.csv")
summary(pa2)
table(pa2)
sd(pa2$ï..Approving)
pa2_approve = rnorm(pa2$ï..Approving, mean=50.09, sd=11.46188 )
plot(pa2_wti2$ï..Approving)
plot(plot(pa2_wti2$ï..Approving, pa2_wti2$ï..Price)
I just started using the awesome gganimate package, and I managed to create a pretty cool animated gif.
However, I would like the image to move from one state to another on click, not automatically. Is there a way to do that with the gganimate package or with another package?
Thank you,
Sarah
I am 2 short of reputations for commenting hence answering directly, otherwise would have asked for data & code, nevertheless I'll try to answer based on understanding from the linked gif.
Since the main aim of gganimate is to create animations which are simply stitched frames from ggplot output, so to my knowledge there is no option to have a click functionality directly.
This would require a package which has capability for interactive graphics, hence plotly is best option. Not trying to demean gganimate (I am myself a big fan of it).
library(plotly)
library(ggplot2)
df <- data.frame(Dim1 = runif(100,-200,200), Dim2 = rpois(100,5),
Timepoint = rep(c("PRE","4WP"),50), pop = runif(100,1,10))
gg <- ggplot(df, aes(Dim1, Dim2)) +
geom_point(aes(size = pop, frame = Timepoint))
ggplotly(gg) %>%
animation_opts(
frame = 1000,
transition = 1000,
easing = "linear",
redraw = TRUE,
mode = "immediate"
)
you can try more easing options from plotly/animation_attributes.js.
This will directly create a interactive plot:
Another option would be to use same animations from gganimate by first saving each frame generated by it in file system using: (as I dont know how you are creating your animation I will create a basic one)
p <- gg + transition_states(Timepoint, transition_length = 100, state_length = 5)
animate(p, renderer = file_renderer(prefix = "gganim_plot", overwrite = TRUE))
which can then be fed into saveHTML command of animation R package.
I have been trying to clean up my project workflow, and have been using the here package, but have am perplexed at some of the utility.
I set up an Rstudio project in the folder ~\ProjFolder. Within this folder I added a Plots folder ~\ProjFolder\Plots.
But when I try to use ggsave to save a plot into the Plots folder it instead places it in the ProjFolder.
library(here)
library(ggplot2)
xdat = rnorm(10)
ydat = rnorm(10)
df = data.frame(xdat,ydat)
ggplot(data = df, aes(x = xdat, y = ydat)) + geom_point()
here("Plots", ggsave("ScatterPlot.jpg"))
Any help? Or am I just using the here package ineffectively?
You should do ggsave(here("Plots", "ScatterPlot.jpg")). here::here is just a way to provide the right file path, you put it in as a replacement for the path argument in functions that take one.
The problem is that you are composing here() and ggsave() in the wrong order. You want the first argument to ggsave() to be the full path, so
ggsave(here("Plots", "ScatterPlot.jpg"))
Does what you want.
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")
})
I've been trying to draw two plots using R's ggplot library in RStudio. Problem is, when I draw two within one function, only the last one displays (in RStudio's "plots" view) and the first one disappears. Even worse, when I run ggsave() after each plot - which saves them to a file - neither of them appear (but the files save as expected). However, I want to view what I've saved in the plots as I was able to before.
Is there a way I can both display what I'll be plotting in RStudio's plots view and also save them? Moreover, when the plots are not being saved, why does the display problem happen when there's more than one plot? (i.e. why does it show the last one but not the ones before?)
The code with the plotting parts are below. I've removed some parts because they seem unnecessary (but can add them if they are indeed relevant).
HHIplot = ggplot(pergame)
# some ggplot geoms and misc. here
ggsave(paste("HHI Index of all games,",year,"Finals.png"),
path = plotpath, width = 6, height = 4)
HHIAvePlot = ggplot(AveHHI, aes(x = AveHHI$n_brokers))
# some ggplot geoms and misc. here
ggsave(paste("Average HHI Index of all games,",year,"Finals.png"),
path = plotpath, width = 6, height = 4)
I've already taken a look here and here but neither have helped. Adding a print(HHIplot) or print(HHIAvePlot) after the ggsave() lines has not displayed the plot.
Many thanks in advance.
Update 1: The solution suggested below didn't work, although it works for the answer's sample code. I passed the ggplot objects to .Globalenv and print() gives me an empty gray box on the plot area (which I imagine is an empty ggplot object with no layers). I think the issue might lie in some of the layers or manipulators I have used, so I've brought the full code for one ggplot object below. Any thoughts? (Note: I've tried putting the assign() line in all possible locations in relation to ggsave() and ggplot().)
HHIplot = ggplot(pergame)
HHIplot +
geom_point(aes(x = pergame$n_brokers, y = pergame$HHI)) +
scale_y_continuous(limits = c(0,10000)) +
scale_x_discrete(breaks = gameSizes) +
labs(title = paste("HHI Index of all games,",year,"Finals"),
x = "Game Size", y = "Herfindahl-Hirschman Index") +
theme(text = element_text(size=15),axis.text.x = element_text(angle = 0, hjust = 1))
assign("HHIplot",HHIplot, envir = .GlobalEnv)
ggsave(paste("HHI Index of all games,",year,"Finals.png"),
path = plotpath, width = 6, height = 4)
I'll preface this by saying that the following is bad practice. It's considered bad practice to break a programming language's scoping rules for something as trivial as this, but here's how it's done anyway.
So within the body of your function you'll create both plots and put them into variables. Then you'll use ggsave() to write them out. Finally, you'll use assign() to push the variables to the global scope.
library(ggplot2)
myFun <- function() {
#some sample data that you should be passing into the function via arguments
df <- data.frame(x=1:10, y1=1:10, y2=10:1)
p1 <- ggplot(df, aes(x=x, y=y1))+geom_point()
p2 <- ggplot(df, aes(x=x, y=y2))+geom_point()
ggsave('p1.jpg', p1)
ggsave('p2.jpg', p2)
assign('p1', p1, envir=.GlobalEnv)
assign('p2', p2, envir=.GlobalEnv)
return()
}
Now, when you run myFun() it will write out your two plots to .jpg files, and also drop the plots into your global environment so that you can just run p1 or p2 on the console and they'll appear in RStudio's Plot pane.
ONCE AGAIN, THIS IS BAD PRACTICE
Good practice would be to not worry about the fact that they're not popping up in RStudio. They wrote out to files, and you know they did, so go look at them there.