R_plotting points in multiple plots - r

I have two plots and I want to add some additional lines to both plots. Is there a way in R to choose the plot (among the two) to draw the new lines?
Edit1:
Actually I have multiple plots in one window using mfrow
Edit2:
I have edited the the question to include the problem i faced after using mfgin par()
x=1:10
y=seq(10,100,10)
z=seq(100,1000,100)
par(mfrow=c(2,1))
plot(x,y)
abline(a=0,b=10,col="blue")
plot(x,z)
abline(a=0,b=100,col="blue")
which gives
But when I use
x=1:10
y=seq(10,100,10)
z=seq(100,1000,100)
par(mfrow=c(2,1))
plot(x,y)
plot(x,z)
par(mfg=c(1,1))
abline(a=0,b=10,col="blue")
par(mfg=c(2,1))
abline(a=0,b=100,col="blue")
the result is
Note the false behavior of the first abline
Can anyone explain the reason and a solution for this?

Assuming you have multiple graphics windows open, you want to use the dev.cur(), dev.next(), dev.set(), dev.list() functions (see ?dev.cur) to identify the current graphics device and switch among devices.
If on the other hand you have set up multiple plots within a single window via the mfrow or mfcol parameters to par(), you can use par("mfg") to query/set which plot is current.
If you use layout, lattice, ggplot2, or raw grid graphics, I'm not sure.

Related

creating multiple file types while plotting

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.

multiple plots with ggplots plotted in sequence without using the graphics position

Is there any way to plot multiple graphics using ggplots2 for the graphics that are built in sequence but other scripts are invoked in between?
grid.arrange is practical but requires all plots to be defined. the solution given in the discussion
Combined plot of ggplot2 (Not in a single Plot), using par() or layout() function?
can be used but requires to know the sequence or column of the graphics
print(plot1, vp = vplayout(1, 1))
how is it possible like par() to open the device with the number of graphics to plot and like any function such as plot, plot the graphics without knowing in which position or column we're going to plot?
Hope it's clear.
Carol

multi paneled graphs: box plot and spagetti plot

I'm trying to create multiple graphs on one panel. I'm hoping for a box plot on both sides of a spaghetti plot.
This is an example of my code:
par(mfrow=c(1,3))
boxplot(h~y,dat,
xlab="Y",
ylab="Incidence 1 (percent)",
main="H",
scales=list(x=list(at=c(1,2))))
xyplot(H~Yr,groups=Subject,type="b",data=data,
ylab="Incidence (percent)",
xlab="Year",
main="Incidence",
scales=list(x=list(at=c(1,2))))
boxplot(h1~y1,dat1,
xlab="Y",
ylab="Incidence 2 (percent)",
main="R",
scales=list(x=list(at=c(1,2))))
When I plot my first box plot things look ok (there is still empty space ready to be filled), but once the spaghetti plot is added in, the whole graph is the spaghetti plot (the box plot is erased).
Is there a way to do multiple but different types of graphs on one panel?
As #DWin and #mnel point out, you are having trouble because you are trying to mix base graphics (boxplot()) and grid-based graphics (xyplot()). To get two boxplots and a spaghetti plot in a single figure, you have three main options. The first two will be much easier than the third:
Use just base graphics (here boxplot() and plot( , type="b")), arranging them in a single figure with par(mfrow=c(1,3).
Use just grid-based graphics (here the lattice functions bwplot() and xyplot( , type="b")), arranging them in a single figure with grid.arrange() from the gridExtra package.
Use a mixture of base and grid-based graphics (like you're trying to do now), combining them in a single figure with functions from the gridBase package.
The only thing to be said for option 3 is that pursuing it will teach you a lot about the low-level implementation of both the base and grid graphical systems!

How to add points to two plots parallelly ? (in R)

I am looking for ways to add points to three different plots in parallel.
I have three scatter plots named s3d1, s3d2 and s3d3 in a single window
layout(matrix(c(1,2,1,3),2, 2, byrow = TRUE))
s3d1<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
s3d2<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
s3d3<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
If I try to add points to s3d1,
s3d1$points3d(mtcars[,3],mtcars[,4],mtcars[,5],col="red")
The points would go to s3d3 but not s3d1. What am I missing ?
More info : I obtain data points while running a program. So, I need to add points to each of these plots as-and-when I get the data specific to that particular plot.
Update :
Tried par() function as well
par(fig=c(0,0.65,0,1), new=TRUE)
s3d1<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
par(fig=c(0.7,1,0.5,1), new=TRUE)
s3d2<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
par(fig=c(0,0.65,0,1), new=TRUE)
s3d1$points3d(mtcars[,3],mtcars[,4],mtcars[,5],col="red")
s3d1$points3d doesn't add new points to s3d1 (and not even to s3d2). Any ideas ?
If you look at the source of points3d() by just trying to execute s3d1$points3d, you'll see that it just adds points to an existing plot that is assumed to be already open. In other words, the points/plot are not stored in the s3d1,2,3 objects, but simply the transformation info needed to plot to the different views.
Soo, to do what you're trying to do, you'll just have to use the normal graphics device commands. For instance, dev.new will open a new plot window, and dev.set can switch between the active ones. You could do something like:
dev.new(); h1=dev.cur()
s3d1<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
dev.new(); h2=dev.cur()
s3d2<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
dev.new(); h3=dev.cur()
s3d3<-scatterplot3d(mtcars[,3],mtcars[,4],mtcars[,5],main="common",pch=20)
dev.set(h1)
s3d1$points3d(mtcars[,3],mtcars[,4],mtcars[,5],col="red")
Also check out ?dev.new for more info.

Is it possible to rotate a plot in R (base graphics)?

I searched for this and found that with {grid} there are ways to rotate an image, and that for some plots you can play with their rotation (for example plot(x,y) instead of plot(y,x)).
However, I want to know if there is a generic method to rotate a plot in R (one that would work for ANY plot generated in base graphics) ?
you could export the graphic, read it back in, and display it rotated as a rasterGrob, say, (or a rasterImage after rotating the matrix, or a grImport grob if you want vector paths)
plot(1:10, rnorm(10))
library(grid)
cap <- grid.cap()
grid.newpage()
grid.raster(cap, vp=viewport(angle=30))
The new gridGraphics package may now be a better alternative.
Note: this doesn't seem to work with Rstudio's graphics device, presumably they haven't implemented grid.cap.
It's kind of possible via the gridGraphics package, although it feels a bit rough on the edges (the examples in ?grid.echo don't all work for me),
plot(1:10, rnorm(10))
library(gridGraphics)
grab_grob <- function(){
grid.echo()
grid.grab()
}
g <- grab_grob()
grid.newpage()
pushViewport(viewport(width=0.7,angle=30))
grid.draw(g)
I'm reasonably certain that there isn't a way with base graphics itself to do this generically. There is however the gridBase package which allows one to mix base graphics and grid graphics in a 'plot'. The vignette for the package has a section on embedding base graphics in grid viewports, so you might look there to see if you can cook up a grid wrapper around your plots and use grid to do the rotation. Not sure if this is a viable route but is, as far as I know, the on only potential route to an answer to your Q.
gridBase is on CRAN and the author is Paul Murrell, the author of the grid package.
After browsing the vignette, I note one of the bullets in the Problems and Limitations section on page, which states that it is not possible to embed base graphics into a rotated grid viewport. So I guess you are out of luck.
Spinning 3D Scatterplots
You can also create an interactive 3D scatterplot using the plot3D(x, y, z) function in the rgl package. It creates a spinning 3D scatterplot that can be rotated with the mouse. The first three arguments are the x, y, and z numeric vectors representing points. col= and size= control the color and size of the points respectively.
# Spinning 3d Scatterplot
library(rgl)
plot3d(wt, disp, mpg, col="red", size=3)
A function rotate_plot to be used like
rotate_plot(some_base_plot(x, y, ...))
isn't possible because most of the base plot don't return a value.
Some of the plots contain a horiz argument to allow you to choose which way round you want the plot drawing. Take a look at barplot.default to see how to implement this. (Warning: it's messy.)
#ucfagls's suggestion to use gridBase is your best bet. There are some examples of its use in Appendix B of Murrell's R Graphics.
Given that its possible to write your own plot functions using base graphics, I can't see how a single solution could exist. Is what you want really just a way to rep lace x data with y data? What exactly do you mean by "rotate"?
Yes it is possible to rotate the the plot in R
by using the function Coord flip() in r
you can flip the graph from horizontal to vertical and from vertical to horizontal.

Resources