I am using GGally::pairs to look at 63 columns of numerical data. The function runs fine but the result is a plot where I can't read any of the column names fully or the numbers (correlations etc.). The resolution is fine, it is just that the plot is compressed so that the plots are tiny and cant really be read (and only part of the text is visible). This is because it prints the plot to the plot viewer in Rstudio I suppose. How can I get the plot to be bigger so I can actually see the results
Revising my comment above, instead of ggsave() that I'm not sure can work, this might work, but assumes plotly accommodates the geoms in your plot (it does for a good number of ggplot geoms, but not all, eg many of the library(ggridges)'s geoms).
library(plotly)
library(htmlwidgets)
p <- ggplot(your ggplot data/parameters/geoms) #creates ggplot object
p <- ggplotly(p) #converts p to html, renders in RStudio console
htmlwidgets::saveWidget(as_widget(p), "filename.html") #saves as a single html file
Related
I'm using ggsave() function to save my ggplots but I have a little problem with that. It occurs that my ggsave() is saving only my last plot (so for example if I have 6 side by side plots I have only saved last one). I know that it's not a problem, because ggsave by default is saving last plot, but I cannot find how can I change it to save all plots.
To summarize :
library(gridExtra)
grid.arrange(qplot(1:10,1:10),qplot(1:10,1:10))
ggsave(file=random.png)
what I want to have :
what I have :
ggsave default plot argument is last_plot(), you can change it and give your saved plot.
library(gridExtra)
temp <- grid.arrange(qplot(1:10,1:10),qplot(1:10,1:10))
ggsave(file='random.png', temp)
In ggplot2, one can easily save a graphic into a R object.
p = ggplot(...) + geom_point() # does not display the graph
p # displays the graph
The standard function plot produces the graphic as a void function and returns NULL.
p = plot(1:10) # displays the graph
p # NULL
Is it possible to save a graphic created by plot in an object?
base graphics draw directly on a device.
You could use
1- recordPlot
2- the recently introduced gridGraphics package, to convert base graphics to their grid equivalent
Here's a minimal example,
plot(1:10)
p <- recordPlot()
plot.new() ## clean up device
p # redraw
## grab the scene as a grid object
library(gridGraphics)
library(grid)
grid.echo()
a <- grid.grab()
## draw it, changes optional
grid.newpage()
a <- editGrob(a, vp=viewport(width=unit(2,"in")), gp=gpar(fontsize=10))
grid.draw(a)
I am very late to this, but it was the first question which showed up when I searched for the question. So I'd like to add my solution for future viewers who come across the question.
I solved this by using a function instead of an object. For example, suppose we want to compare two beta distributions with different parameters. We can run:
z1<-rbeta(10000,5,5)
z2<-rbeta(10000,20,20)
plotit<-function(vector,alpha,beta){
plot(density(vector),xlim=c(0,1))
abline(v=alpha/(alpha+beta),lty="longdash")
}
And save the plots as functions rather than objects.
z.plot1<-function(){plotit(z1,5,5)}
z.plot2<-function(){plotit(z2,20,20)}
Next, we can call each plot as we want by simply calling the two plots as functions rather than objects.
z.plot1()
plots the first plot and
z.plot2()
plots the second.
Hope that helps someone who stumbles across this later!
You can use the active binding feature of the pryr package if you don't want to directly change the values of the object created.
library(pryr)
a %<a-% plot(1:10,1:10)
Each time you type a on the console the graph will be reprinted on the screen. The %<a-% operator will rerun the script every time (in case of one graph this is not a problem I think). So essentially every time you use a the code will be rerun resulting in your graph which of course you can manipulate (overlay another plot on top) or save using png for example. No value itself will be stored in a however. The value will still be NULL.
I don't know if the above is what you are looking for but it might be an acceptable solution.
library(ggplot2)
# if mygraph is a plot object
ggsave("myplot1.png",mygraph)
# if the plot is in a list (e.g. created by the Bibliometrics package)
ggsave("myplot1.png",mygraphs[[1]])
I want to add an additional tick to my plot in ggplot2, and used Solution 2 as described in the post Annotate ggplot with an extra tick and label.
It worked fine for me, giving the following result in R Studio:
But when I try to save the result using ggsave() to create the a .pdf, .ps, or .png file, the red number is cut off half like this:
I have the feeling that the inner plot is printed first and later the margins are plotted on top of this.
Anybody has a hint?
Thank you Z. Lin! I just had a grid.draw(g) instead of g <- grid.draw(g). This dot in R always activates my python brain region :)
I've read all posts relevant to this problem.But the truth is: if you have lots of variables to plot,this problem still occur.
My laptop resolution is 1080p, I open rstudio and run below script:
a<-iris[,1:4]
> a<-t(a)
> a<-as.data.frame(a)
> pairs(a)
Error in plot.new() : figure margins too large
I have tried all the solution in this site from similar questions, none is workable.
I really need this plot but cannot get it.How to solve this problem?
The only way I can possibly imagine doing this is (as I think has previously been suggested) sending the output to a PDF file and then using a PDF viewer to look at it. (My answer is very similar to the answer you got to this question, except that I'm using PDF rather than PNG as output ... tried it for PNG as well, seems to work for 2000x2000 pixels ...)
For smaller/reasonable examples, zooming and/or opening an external graphics window with dev.new() should work ...
a <- iris[,1:4]
a <- t(a)
a <- as.data.frame(a)
pdf(file="tmp.pdf",width=100,height=100)
pairs(a,gap=0,pch=".")
dev.off()
This took about 18 seconds on my laptop and produced a 1.2M PDF file. Here's what the picture looked like when I zoomed all the way out ("fit to window") in my PDF viewer:
If you have 150x150 subplots and want to render each one at 1 cm wide x 1 cm tall (which seems pretty small for viewing any detail), you're either going to need a very high-resolution projector or a large-format (poster) printer. You could scroll around the image with a PDF viewer, but it doesn't seem very practical ...
I'll answer in two ways. Firstly, as you're using the iris dataset, are you sure you want a pairs plot of the transpose of a? That would mean comparing the individual flowers, rather than the features (like sepal length etc). Is this what you want instead?
> a <- iris[,1:4]
> pairs(a)
This will give you a 4x4 pairs plot (comparing the flower features). If however, you really do want a pairs plot between observations instead of features, then you're asking for a 150x150 pairs plot! It seems to me that the only way to do that is to generate multiple pairs plots, each one for a subset of those 150 items.
The problem seems to be caused because the image will not fit into the graphics window as rendered for the global settings. Make sure that your zoom is not set beyond 100 %
RStudio simply cannot show very large plots. If you have a grouping variable, specify the rows for each category/factor and plot again; this becomes a smaller plot:
EX: If you have a dataframe with 100 rows for 2 groups x and y as in the column 'groups', and 20 columns as variables to plot for each group, to get the plots for all columns for the x (corresponding to rows 1:50):
library(tidyverse)
df[1:50,] %>%
keep(is.numeric) %>%
gather() %>%
ggplot(aes(value)) +
facet_wrap(~ key, scales = "free") +
geom_histogram()
hope this helps!
I would like to produce a series of plots in both high-resolution and low-resolution versions, or stated differently using two different file types (.png and .eps). I'd like to know the best/least repetetive way to do this. I am using the gplot function in sna, and the plot has a custom legend outside the plot area. I wrote a function something like this:
library(sna)
plotfun <- function(net){
png("test.png",width=800)
p <- gplot(net)
par(xpd=T)
legend(max(p[,1])+1,max(p[,2]),legend=letters[1:10],title="custom legend")
dev.off()
seteps()
postscript(test.eps)
#repeat all the plotting commands, which are much longer in real life
dev.off()
}
#try it with some random data
plotfun(rgraph(10))
This is perfectly functional but seems inefficient and clumsy. The more general version of this question is: if for any reason I want to create a plot (including extra layers like my custom legend), store it as an object, and then plot it later, is there a way to do this? Incidentally, this question didn't seem sna specific to me at first, but in trying to reproduce the problem using a similar function with plot, I couldn't get the legend to appear correctly, so this solution to the outside-the-plot-area legend doesn't seem general.
I would recommend generate graphs only in Postscript/PDF from R and then generate bitmaps (e.g. PNG) from the Postscript/PDF using e.g. ImageMagick with -density parameter (http://www.imagemagick.org/script/command-line-options.php#density) set appropriately to get desired resolution. For example
convert -density 100 -quality 100 picture.pdf picture.png
assuming picture.pdf is 7in-by-7in (R defaults) will give you a 700x700 png picture.
With this approach you will not have to worry that the picture comes out formatted differently depending which R device (pdf() vs png()) is used.