I've two datas to compare in a scatter plot.
data1 <-c(0.341, 0.655, 0.934, 1.741)
data2 <-c(1.8, 2, 2.4, 2.6)
With the code below I am getting this:
plot(data1, data2, main="Minute Max.", asp=1,
xlab="Historical Values ", ylab="Disaggregated Values", pch=19)
I have three wishes:
1) Adding a 45 degree line
2) Having same coordinate length. For the example above, you can see the max. value is 2.6 in total. So I want my scatter diagram as square. Both x and y coordinates lengths' must be 2.6.
3) I know how to export the plot manually. But which code should I use to export the plot?
1) Use abline to draw a straight line. This is called after your plot.
plot(data)
abline(0,1)
abline() also takes additional arguments, like col="red".
2) This can be done using xlim and ylim. For more information on how you can edit the plot, use ?plot() inside R to see the revelant helpfile.
plot(data, xlim=c(0,2.6),ylim=(0,2.6)
3) If you want it saved as e.g. a pdf, you can do the following.
pdf("myfile.pdf")
plot(data,....)
dev.off()
Also works with jpeg, e.g.
jpeg("myplot.jpg")
plot(data)
dev.off()
I want to put two plots on the same pdf page.
The first plot needs an aspect ratio of 1.
x <- 1:5
y <- 1:5
z <- 1:5
t <- 1:5
pdf("test.pdf")
par(mfrow=c(2,1))
plot(x,y,asp=1)
plot(z,t)
dev.off()
I end up with the following:
Let's say negative values have no meaning in the context of the first plot. How can I do to get a square plot instead of this horizontally spread rectangle ?
I tried specifying xlim=c(0, 6) and ylim=c(0, 6), but the plot is still a long rectangle with empty spaces on both sides of the points. Besides, I may not know in advance what the highest values are.
Ideally, I would like to be able to say: For the first plot, start the axes at 0, use the same length for both axes, fit the first plot in the first half of an A4 page, and the second plot in the second half of the same page.
How can I do this ?
A tact to force square plotting regions is to add pty="s" to the par function:
pdf("temp.pdf", height=11, width=8.5)
par(mfrow=c(2,1), pty="s")
plot(x,y,asp=1, xlim=c(0, 6))
plot(z,t, xlim=c(0, 6))
dev.off()
From the help file, ?par, the pty argument takes
A character specifying the type of plot region to be used; "s" generates a square plotting region and "m" generates the maximal plotting region.
Maybe you can change pdf's width and height like this:
pdf("test.pdf",width=2.height=5)
and then
par(mfrow=c(2,1))
plot(x,y)#remove asp=1
plot(z,t)
dev.off()
I have found that when I try to overlay multiple rasters using plot(...,add=T) if I try to overlay more than 3 rasters together the subsequent plot does not align the rasters properly.
My original intent was to create a categorical map of modeled landcover where the darkness of the color representing a cover class varied wrt the certainty in our model projection. To do this, I created a simple script that would loop through each cover class and plot it (e.g., forest, green color on map) using a color gradient from grey (low certainty forest prediction) to full cover color (e.g., dark green for areas are strongly predicted).
What I have found is that using this approach, after the 3rd cover is added to the plot, all subsequent rasters that are overlayed on the plot are arbitrarily misaligned. I have reversed the order of plotting of the cover classes and the same behavior is exhibited meaning it is not an issue with the individual cover class rasters. Even more puzzling in Rstudio, when I use the zoom button to closely inspect the final plot, the misalignment worsens.
Do you have any ideas of why this behavior exists? Most importantly, do you have any suggested solutions or workarounds?
The code and data on the link below has all of the behaviors described captured.
https://dl.dropboxusercontent.com/u/332961/r%20plot%20raster%20add%20issue.zip
Turn plot_gradient=F to see how if you just simply subset a same raster and add the subsets sequentially to the same plot you can replicate the issue. I have already tried setting the extent of the plot device plot(..., ext) but that did not work. I have also checked and the extent of each cover raster is the same.
Below is the figure of the misaligned cover classes. plotting to jpeg device will result in a similar image (i.e., this is not an issue of Rstudio rendering).
Strangely enough, if I zoom into the image using Rstudio, the misalignment is different
For comparison, this is how the covers should align correctly in the landscape
library(raster)
library(colorRamps)
raster_of_classes=raster("C:/r plot raster add issue/raster_of_classes.tif")
raster_of_certainty_of_classes=raster("C:/r plot raster add issue/raster_of_certainty_of_classes.tif")
endCols=c("darkorchid4", "darkorange3", "red3", "green4", "dodgerblue4") #colors to be used in gradients for each class
classes=unique(raster_of_classes)
minVal=cellStats(raster_of_certainty_of_classes, min)
tmp_i=1
addPlot=F
plot_gradient=F #this is for debug only
#classes=rev(classes) #turn this off and on to see how last 2 classes are mis aligned, regardless of plotting order
for (class in classes){
raster_class=raster_of_classes==class #create mask for individual class
raster_class[raster_class==0]=NA #remove 0s from mask so they to do not get plotted
if (plot_gradient){
raster_of_certainty_of_class=raster_of_certainty_of_classes*raster_class #apply class mask to certainty map
}else{
raster_of_certainty_of_class=raster_class #apply class mask to certainty map
}
endCol=endCols[tmp_i] #pick color for gradient
col5 <- colorRampPalette(c('grey50', endCol))
if (plot_gradient){
plot(raster_of_certainty_of_class,
col=col5(n=49), breaks=seq(minVal,1,length.out=50), #as uncertainty values range from 0 to 1 plot them with fixed range
useRaster=T, axes=FALSE, box=FALSE, add=addPlot, legend=F)
}else{
plot(raster_of_certainty_of_class,
col=endCol,
useRaster=T, axes=FALSE, box=FALSE, add=addPlot, legend=F)
}
tmp_i=tmp_i+1
addPlot=T #after plotting first class, all other classes are added
}
I had this problem too and solved it by calling the graphical parameters function, par(), with a subset of parameters, and most importantly, put the new=TRUE in the par() call, not the plot() call, before each additional plot() call. For example:
png(fullname,
width = 3000,
height= 3000)
# original par() call
par(mfrow=c(1,1), cex=3, mar=c(3,3,3,7), bg=bgcol, col=txtcol)
# first plot
plot(zreate,
maxpixels=ncell(zreate),
col=qcol,
colNA=mapbg,
xaxt='n',
yaxt='n',
ext=map_extent,
breaks=tq,
bty='n',
legend=FALSE)
#second plot and par() call
par(mfrow=c(1,1), cex=3, mar=c(3,3,3,7), bg=bgcol, col=txtcol, new=TRUE)
plot(rt,
maxpixels=ncell(rt),
col=dcol,
legend=FALSE,
xaxt='n',
yaxt='n',
ext=map_extent,
bty='n')
#third plot and par() call
par(mfrow=c(1,1), cex=3, mar=c(3,3,3,7), bg=bgcol, col=txtcol, new=TRUE)
plot(r0,
maxpixels=ncell(r0),
col="#9e9ac8",
xaxt='n',
yaxt='n',
ext=map_extent, #PRENAFILTERING fix
bty='n',
legend=FALSE)
In December 2013, I posted a question about exactly this behavior to the R-sig-geo mailing list, and got no useful response (other than a confirmation that it also happens with R versions and OS's different than my own).
Here, for the record, is the reproducible example that I used to illustrate the issue. (See the linked question for some more explanation.)
library(maptools) ## Only needs to be installed for example data
library(raster)
library(rgeos)
## Create an example raster
p <- shapefile(system.file("shapes/co37_d90.shp", package="maptools"))
p <- p[31,] ## A tall narrow county polygon
pr <- gDifference(gBuffer(p, width=.01), p)
r <- rasterize(pr, raster(extent(pr), ncol=100, nrow=100))
## These three are properly registered on one another
plot(r, col="yellow", legend=FALSE)
plot(r, col="green", legend=FALSE, add=TRUE)
plot(r, col="grey", legend=FALSE, add=TRUE)
## All subsequent "layers" are improperly shifted/skewed to right
plot(r, col="yellow", legend=FALSE, add=TRUE)
plot(r, col="blue", legend=FALSE, add=TRUE)
plot(r, col="red", legend=FALSE, add=TRUE)
plot(r, col="grey20", legend=FALSE, add=TRUE)
## Following the above, SpatialPolygons are also shifted/skewed
plot(p, border="red", lwd=2, add=TRUE)
I have run into the same problem and found an answer that is less of a hack than the previous answer. It follows the train of thought described by user "Dial".
The key is to use image(). But add in the argument maxpixels = ncell(x). This way, the resolution is maintained and pixel aggregation does not occur either as much or at all.
> x <- brick(image.path)
> plotRGB(x)
> image(brick.overlay, add = T, col = 'black', maxpixel = ncell(x))
> image(brick.overlay, add = T, col = 'yellow', maxpixel = ncell(x))
The "brick.overlay" would be some mask object, region of interest, or otherwise subsetted data where data is associated with those pixels and all other pixels are NA.
The brick.overlay object should have to have an implied extent based on total number of pixels where all non-interest pixels are NA.
This is hardly the most memory efficient way, but it's the one I know works.
If you use "Dial's" example, I think you would do:
image(r, col="yellow", add=TRUE, maxpixels = ncell(r))
Interesting problem. As you likely know, image() doesn't seem to have the same issue but generally makes uglier maps, right?
library(raster)
library(rgeos)
## Create an example raster
p <- shapefile(system.file("shapes/co37_d90.shp", package="maptools"))
p <- p[31,] ## A tall narrow county polygon
pr <- gDifference(gBuffer(p, width=.01), p)
r <- rasterize(pr, raster(extent(pr), ncol=100, nrow=100))
## These three are properly registered on one another
image(r, col="yellow")
image(r, col="green", add=TRUE)
image(r, col="grey", add=TRUE)
## All subsequent "layers" are also registered
image(r, col="yellow", add=TRUE)
image(r, col="blue", add=TRUE)
image(r, col="red", add=TRUE)
image(r, col="grey20", add=TRUE)
## Following the above, SpatialPolygons are no longer shifted/skewed
plot(p, border="red", lwd=2, add=TRUE)
I'm fairly new to r and I have to plot the scatter plot with:
residues1 residues2 coovariance
1 1 0.99613318
2 1 0.98771518
3 1 0.98681384
4 1 0.99225447
residue 1 and residue2 as x,y axis and the coovariance is to be color scale rather than height. I have previously used scatter plot 3d but don't know how to plot the third axis as a color scale. Please help .
Thanks
Vibhor
I'm not sure an x-y plot with color per column 3 is the best way to visualize this. If residues2 is a constant, prob. better to leave it out altogether and plot the other values against each other.
Perhaps you could adapt the following to your needs:
df1 <- data.frame(r1=seq(4), r2=rep(1,4),
c1=c(0.99613318, 0.98771518, 0.98681384, 0.99225447) )
### give order (for plotting)
df1 <- within(df1, c2 <- rank(c1))
### create blank plot
with(df1, plot(r1,r2, xlab="residues_1", ylab="residues_2", cex.lab=1.5))
### strongest red to largest color
with(df1, points(r1, r2, cex=15, pch=19, col = rev(heat.colors(4))[c2] ))
### make legend
l1 <- as.matrix(df1[ ,"c1"])
graphics::legend("topright", legend=l1, lty=1, title="covariance", lwd=3,
col = rev(heat.colors(4))[df1$c2], cex=2)
giving:
(I've made the image elements a bit oversize, and manually adjusted dimensions before saving as .png in order to display better on here).
Scatter plots can be hard to interpret when many points overlap, as such overlapping obscures the density of data in a particular region. One solution is to use semi-transparent colors for the plotted points, so that opaque region indicates that many observations are present in those coordinates.
Below is an example of my black and white solution in R:
MyGray <- rgb(t(col2rgb("black")), alpha=50, maxColorValue=255)
x1 <- rnorm(n=1E3, sd=2)
x2 <- x1*1.2 + rnorm(n=1E3, sd=2)
dev.new(width=3.5, height=5)
par(mfrow=c(2,1), mar=c(2.5,2.5,0.5,0.5), ps=10, cex=1.15)
plot(x1, x2, ylab="", xlab="", pch=20, col=MyGray)
plot(x1, x2, ylab="", xlab="", pch=20, col="black")
However, I recently came across this article in PNAS, which took a similar a approach, but used heat-map coloration as opposed to opacity as an indicator of how many points were overlapping. The article is Open Access, so anyone can download the .pdf and look at Figure 1, which contains a relevant example of the graph I want to create. The methods section of this paper indicates that analyses were done in Matlab.
For the sake of convenience, here is a small portion of Figure 1 from the above article:
How would I create a scatter plot in R that used color, not opacity, as an indicator of point density?
For starters, R users can access this Matlab color scheme in the install.packages("fields") library, using the function tim.colors().
Is there an easy way to make a figure similar to Figure 1 of the above article, but in R? Thanks!
One option is to use densCols() to extract kernel densities at each point. Mapping those densities to the desired color ramp, and plotting points in order of increasing local density gets you a plot much like those in the linked article.
## Data in a data.frame
x1 <- rnorm(n=1E3, sd=2)
x2 <- x1*1.2 + rnorm(n=1E3, sd=2)
df <- data.frame(x1,x2)
## Use densCols() output to get density at each point
x <- densCols(x1,x2, colramp=colorRampPalette(c("black", "white")))
df$dens <- col2rgb(x)[1,] + 1L
## Map densities to colors
cols <- colorRampPalette(c("#000099", "#00FEFF", "#45FE4F",
"#FCFF00", "#FF9400", "#FF3100"))(256)
df$col <- cols[df$dens]
## Plot it, reordering rows so that densest points are plotted on top
plot(x2~x1, data=df[order(df$dens),], pch=20, col=col, cex=2)
You can get a similar effect by doing hexagonal binning, divide the region into hexagons, color each hexagon based on the number of points in the hexagon. The hexbin package has functions to do this and there are also functions in the ggplot2 package.
You can use smoothScatter for this.
colramp = colorRampPalette(c('white', 'blue', 'green', 'yellow', 'red'))
smoothScatter(x1, x2, colramp=colramp)