How to add points to two plots parallelly ? (in R) - 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.

Related

How to delete the last page from grid/grDevices?

Is there a method to delete the last page created with the grid.newpage() or revert the graphic device to the state before the last plot was added?
Background:
I wrote a function that adds a layer (eg. geom_label) to an existing ggplot with location of data points based on the absolute plot dimensions (eg. inches/lines), rather than data range.
The procedure is: produce a plot, print it on the current device, measure the printed grobs and enhance the data frame to be plotted with relevant statistics (eg. origin of the coordinate system per panel, relative units per inch or per line), create the new plot with an additional layer with aesthetics computed with these new variables, print this final plot.
The main purpose was to have a tool that nicely aligns additional text/labels with summary statistics within the plotting area, even when facets or grouping variables are in use.
The issue is that an unnecessary page is produced with the plot I do not really use, except for making measurements, and I did not find any grid or grDevices method to delete the last printed page. Do you know of any such function?
There are some potential flawed workarounds: printing new ggplot object without calling grid.newpage() (but you no longer simply print(plot)), or plotting the first plot in a temporary device with same parameters as the target device (but it's not universal, and requires different approach per device; eg. solutions for .png and multipade .PDF will differ).
Grid units already let you place objects at fixed positions in the panel,
library(ggplot2)
library(grid)
ag <- grobTree(textGrob('+', x = unit(3,"cm"), y=unit(1,'npc') - unit(1,'in')))
qplot(1:10,1:10) +
annotation_custom(ag)

How to keep previous plots and windows in Gnuplot?

I have some problems of using gnuplot. I just begin with it.
(1)What is the command for keeping the previous plot when I plot new data? Do I have to plot the old data and the new data at the same time?
(2)What is the command for open a new window while keep the old ones? Do I have to set the window's id by using, e.g.,
set terminal wxt 3
, before each plot?
Can anyone give me some help or some good references?
Usually, to plot several data set you would use
plot 'data1.dat', 'data2.dat'
You could also use replot to add one of the data sets later
plot 'data1.dat'
...
replot 'data2.dat'
To open a new window, you must use the window's id like with set terminal wxt 2. The old windows stay open, but you cannot interact with them anymore (zooming, scrolling etc.). See also the discussion to the quesiton Two interactive windows in Gnuplot with wxt terminal.
You already wrote the answers of your questions.
1.: You can use the replot command:
plot sin(x)
replot cos(x)
but this just expands to
plot sin(x), cos(x)
So, it replots all data and does not just add the cos(x).
2.: Yes, you can also switch between the windows to update the plots. But note that settings like ranges and labels are not stored per window / plot, but globally. If they are different for different plots, you have to change them every time.
You may also have a look at "set multiplot" to put several plots on one window / picture. But it is not so nice for interactive plotting, as you will notice.
Also, output terminals supporting multiple pages like pdfcairo will add a new page for each plot.

Formatting Issue with barchart() of Cluster Analysis

I've created a segment profile plot of my cluster analysis but I'm having an issue with the formatting of a barchart() command. Here is the chart I created. The obvious issue is that my lines are too close together to read.
Here you can see the code I used to create this chart. Can someone tell me what to add in order to make this chart readable? Below is an example of my code used.
R code for reproducing the clustering and PCA we used:
## if not installed, install: install.packages("flexclust")
library("flexclust")
load("vacpref.RData")
cl6 <- kcca(vacpref, k=vacpref6, control=list(iter=0),
simple=FALSE, save.data=TRUE)
summary(cl6)
hierarchical clustering of the variables
varhier <- hclust(dist(t(vacpref)), "ward")
par(mar=c(0,0,0,15))
plot(as.dendrogram(varhier), xlab="", horiz=TRUE,yaxt="n")
principal component projection
vacpca <- prcomp(vacpref)
R code for generating the Segment Separation Plot
pairs(cl6, project=vacpca, which=1:3, asp=TRUE,points=FALSE,
hull.args=list(density=10))
R code for generating the Segment Positioning Plot:
col <- flxColors(1:6)
col[c(1,3)] <- flxColors(1:4, "light")[c(1,3)]
par(mar=rep(0,4))
plot(cl6, project=vacpca, which=2:3,
col=col,asp=TRUE,points=F,hull.args=list(density=10),axes=FALSE)
projAxes(vacpca, minradius=.5, which=2:3, lwd=2, col=”darkblue”)
R code for generating the Segment Profile Plot:
barchart(cl6, shade=TRUE, which=rev(varhier$order),legend=TRUE)
The last command was the one I used to create my segment profile plot but I wasn't sure if the commands before may have affected it in any way. I'm new to R.
One trick I often use is to change the width/height and resolution through exporting the image. Try this:
png("c:\\temp\\myCrazyPlot.png", res=250, height=8, width=12, unit="in")
barchart(cl6, shade=TRUE, which=rev(varhier$order),legend=TRUE)
# And whatever other plot commands for the same plot
dev.off()
Then go check your .png file. By tinkering the height and width, you can somehow adjust the spacing of the labels at the y-axis. You may even make its height longer than its width to let the labels spread out. (I think currently you can't do that because that's the maximal height of your screen?)

Specify plot area in a multiplot

I create a row of plots in a graphic device with the par() command and run the first 2 plots:
par(mfrow = c(1, 4))
hist(mydata)
boxplot(y ~ x)
Now let's say the boxplot is wrong and I want to replace it with a new one. By default the next plot goes to the left side of the previous one (or one row below, first column, in case of a multiple rows layout), leaving the previous plot unchanged.
Is there a way to specify the location of the next plot in the multiplot grid area?
To specify the location of the next plot in the multiplot grid area, I prefer to use the function layout.
The layout function provides an alternative to the mfrow and mfcol settings.
For example the equivalent of par(mfrow = c(1, 4)) is :
layout(matrix(c(1, 3, 2, 4), byrow=TRUE, ncol=4))
or
layout(matrix(c(1, 2, 3, 4), byrow=TRUE, ncol=4))
The function layout.show() may be helpful for visualizing the figure regions
that are created. The following code creates a figure visualizing the layout
created in the previous example:
layout.show(4)
The base graphics model is ink-on-paper and does not allow revisions. The lattice and ggplot models are based on lists that can be modified. You can "go back" an add items with lines, points and as pointed out you can change the focus to a particular panel, but to remove or replace stuff .... not possible. Re-running the code shouldn't be a big problem, should it? Pixels are very cheap.
You can specify the next frame to plot to useing the mfg argument to par. See ?par for details. So a command like:
par(mfg=c(1,2))
Will mean that the next high level plot will go to the plot in the 1st row 2nd column. This can be used to plot in your own custom order. However, using layout for this is probably easier better in most cases.
When you use this to specify a frame to plot in R assumes that the frame is ready to be plotted in, it will not remove anything already there, so if there is an existing plot there it will be plotted over and you will likely see both plots and it won't look pretty.
You can draw a rectangle over the top of an existing plot to give yourself a blank frame to plot in using code like:
par(xpd=NA)
rect( grconvertX(0, from='nfc'), grconvertY(0,from='nfc'),
grconvertX(1,from='nfc'), grconvertY(1, from='nfc'),
col='white',border='white')
This works OK for looking at on the screen, but you need to be careful with this if exporting or printing, in some cases the printer or interpreter of the graphics file will interpret the white rectangle as "do nothing" and you will again see both plots.
In general it is best to do plots that take more than a line or 2 of code in a script window so that if you want to change something you can edit the script and just recreate the whole plot from scratch rather than relying on tricks like this.

Repeat plot command with minor changes in R

I made a plot in R and I want to repeat all the commands (like plot(), legend() or line()) that were carried out for this plot, with some minor changes. For example I want to set the axes to logarithmic scale and change the title of the plot.
In gnuplot I would use the replot command.
plot ...
set title "The same plot with logarithmic axes"
set logscale
replot
Is something like this possible in R. The only thing that comes to my mind of doing this (besides changing the values manually and re-run the lines of codes) would be setting up a function, that asks for all parameters that might be changed by the user.
Thanks for your help,
Sven
R uses a pen and paper graphics model - once the plot has been drawn on the device that is it. If you want to change some aspect of the plot, you need to replay the graphics function calls that produce the plot with the changes made to the code.
Depending on what you are really doing there are two options:
If this is just for you, write code in a text editor / IDE that knows R and can send chunks of code at a time to R. That way the code to produce the figure is recorded in a separate script which you can paste into/send to R making the changes you need each time to the script.
If you are going to be doing this often, then write yourself a wrapper plotting function that encapsulates the plot code you want but allows you to pass in arguments to alter the aspects you want.
Lattice and ggplot2 are a little different as they are based on grid graphics and create objects that when printed produce a plot on the device. One can manipulate that object to alter what is drawn, and with grid one can push and pop things on to / off a viewport.

Resources