Plotting densities in R - r

So, I am plotting densities (histograms). For example:
d <- density(table[table$position==2,]$rt)
But, I want to plot multiple densities on the same plot. For instance, I also want to plot
density(table[table$position==3,]$rt)
density(table[table$position==4,]$rt)
density(table[table$position==5,]$rt)
Furthermore, I want to specify the center point for each of these densities.
Another way to ask this question is, how can I manually shift a density plot over by a certain number of x units? (for instance, increase all x values by 5)

As with many R analysis functions, saving the output is your friend. So is ?density.
foo<-density(something)
names(foo)
"x", "y" , "bw", "n" , "call" ,"data.name"
So,
plot(foo$x+5, foo$y, t='l')
And you're done so far as I can tell.

For the piece of your question about plotting multiple densities on the same plot, use lines:
dat <- data.frame(x = rnorm(100), y = rnorm(100) + 2, z = rnorm(100) + 5)
plot(c(-2.5,8),c(0,0.5),type = "n")
lines(density(dat$x))
lines(density(dat$y))
lines(density(dat$z))
You open an empty plotting device using plot(...,type = "n") and then draw on it using lines or points, etc.

Related

How to remove colour scale legend from plot() of spp density in R

I am plotting the density of a two-dimensional, weighted spatial point pattern. I'd like to make the plot without a colour scale legend, and save it with no (or minimal) boarders on all sides, like this: My problem is that I can't remove the colour scale legend. Reproducible code below:
## Install libraries:
library(spatstat) #spatial package
library(RColorBrewer) #create custom colour ramps
## Create reproducible data:
data <- data.frame(matrix(ncol = 3, nrow = 50))
x <- c("x", "y", "weight")
colnames(data) <- x
data$x <- runif(50, 0, 20)
data$y <- runif(50, 0, 20)
data$weight <- sample(1:200, 50)
## Set plotting window and colours:
plot.win <- owin(c(0,20), c(0,20)) # plot window as 20x20m
spat.bat.frame <- NULL # create a frame to store values in
cols1<-colorRampPalette(brewer.pal(9,"Blues"))(100) #define colour ramp for density plots
## Create and save plots:
jpeg(filename = "Bad plot.jpeg", res = 300, units = "cm", width = 20, height = 20)
par(mar=c(0,0,0,0),oma=c(0,0,0,0),lwd=1)
ppp_01 <- ppp(x = data$x, y = data$y, window = plot.win)
ppp_02 <- ppp(x = data$x, y = data$y, window = plot.win)
plot(density(ppp_01, weights = data$weights), main=NULL, col=cols1, sigma = 1)
plot(ppp_02, add=TRUE) #add spp points to density plot
dev.off()
I've tried legend=FALSE, auto.key=FALSE, colorkey=FALSE, which don't seem to be compatible with plot() (i.e. they don't give an error but don't change anything). I've also tried some work-arounds like saving a cropped image with dev.off.crop() or by adjusting margins with par(), but haven't been able to completely remove the legend. Does anyone have any suggestions on how to remove a colour scale legend of a density spp (real-valued pixel image) using plot()?
I specifically need to plot the density of the spatial point pattern, to specify a custom colour ramp, and to overlay the spp points onto the density image. I could try plotting with spplot() instead, but I'm not sure this will allow for these three things, and I feel like I'm missing a simple fix with plot(). I can't crop the figures manually after saving from R because there are 800 of them, and I need them all to be exactly the same size and in the exact same position.
Thank you!
Since plot is a generic function, the options available for controlling the plot will depend on the class of object that is being plotted. You want to plot the result of density(ppp_01, weights = data$weights). Let's call this Z:
Z <- density(ppp_01, weights = data$weights, sigma=1)
Note: the smoothing bandwidth sigma should be given inside the call to density
To find out about Z, you can just print it, or type class(Z).
The result is that Z is an object of class"im" (pixel image).
So you need to look up the help file for plot.im, the plot method for class "im". Typing ?plot.im shows that there is an argument ribbon that controls whether or not the colour ribbon is displayed. Simply set ribbon=FALSE in the call to plot:
plot(Z, ribbon=FALSE, main="", col=cols1)
Or in your original code
plot(density(ppp_01, weights=data$weights, sigma=1), main="", col=cols1)
However I strongly recommend separating this into two lines, one which creates the image object, and one which plots the image. This makes it much easier to spot mistakes like the misplacement of the sigma argument.

Multiple Pen's Parade Graphs on the same Plot

I'm doing stochastic dominance analysis with diferent income distributions using Pen's Parade. I can plot a single Pen's Parade using Pen function from ineq package, but I need a visual comparison and I want multiple lines in the same image. I don't know how extract values from the function, so I can't do this.
I have the following reproducible example:
set.seed(123)
x <- rnorm(100)
y <- rnorm(100, mean = 0.2)
library(ineq)
Pen(x)
Pen(y)
I obtain the following plots:
I want obtain sometime as the following:
You can use add = TRUE:
set.seed(123)
x <- rnorm(100)
y <- rnorm(100, mean = 0.2)
library(ineq)
Pen(x); Pen(y, add = TRUE)
From help("Pen"):
add logical. Should the plot be added to an existing plot?
While the solution mentioned by M-M in the comments is a more general solution, in this specific case it produces a busy Y axis:
Pen(x)
par(new = TRUE)
Pen(y)
I would generalize the advice for plotting functions in this way:
Check the plotting function's help file. If it has an add argument, use that.
Otherwise, use the par(new = TRUE) technique
Update
As M-M helpfully mentions in the comments, their more general solution will not produce a busy Y axis if you manually suppress the Y axis on the second plot:
Pen(x)
par(new = TRUE)
Pen(y, yaxt = "n")
Looking at ?ineq::Pen() it seems to work like plot(); therefore, followings work for you.
Pen(x)
Pen(y, add=T)
Note: However, add=T cuts out part of your data since second plot has points which fall out of the limit of the first.
Update on using par(new=T):
Using par(new=T) basically means overlaying two plots on top of each other; hence, it is important to make them with the same scale. We can achieve that by setting the same axis limits. That said, while using add=T argument it is desired to set limits of the axis to not loose any part of data. This is the best practice for overlaying two plots.
Pen(x, ylim=c(0,38), xlim=c(0,1))
par(new=T)
Pen(y, col="red", ylim=c(0,38), xlim=c(0,1), yaxt='n', xaxt='n')
Essentially, you can do the same with add=T.

plotting non-continuous functions in R without vertical lines

I'm plotting some functions in R. Some of them aren't continuous and I get a vertical line between the diferent curve components. I really need to get this vertical line out (It makes the function look like a no-function and I don't want that).
So, how can I do that? Right now, I'm using two vectors x andy and doing plot(x,y,type = "l") so R doesn't understand where there is a discontinuity. But I didn't find a better way.
It might not be the optimum solution, but if the number of functions is small you could split them leaving the continous parts, then just use plot for the first one and add the other with lines. e.g.:
x <- seq(1,3,1)
y <- sqrt(x)
x2 <- seq(3,6,1)
y2 <- runif(4)
plot(y ~ x, type = "l",col = 2 , ylim = c(0,2) , xlim = c(0,6))
lines(y2 ~ x2, col = 2)

R distinct some points with different color

I have around 20.000 points in my scatter plot. I have a list of interesting points and want to show those points in the scatter plot with different color. Is there any simple way to do it? Thank you.
Further explanation,
I have a matrix, consist of 20.000 rows, let's say R1 to R20000 and 4 columns, let's say A,B,C, and, D. Each row has its own row.names. I want to make a scatter plot between A and C. It is easy with plot(data$A,data$B).
On the other hand, I have a list of row.names which I want to check where in the scatter plot those point is. Let's say R1,R3,R5,R10,R20,R25.
I just want to change the color of R1,R3,R5,R10,R20,R25 in the scatter plot different from other points. Sorry if my explanation is not clear.
If your data is in a simple form, then it is easy to do. For example:
# Make some toy data
dat <- data.frame(x = rnorm(1000), y = rnorm(1000))
# List of indicies (or a logical vector) defining your interesting points
is.interesting <- sample(1000, 30)
# Create vector/column of colours
dat$col <- "lightgrey"
dat$col[is.interesting] <- "red"
# Plot
with(dat, plot(x, y, col = col, pch = 16))
Without a reproducible example, it's hard to say anything more specific.

Formatting and manipulating a plot from the R package "hexbin"

I generate a plot using the package hexbin:
# install.packages("hexbin", dependencies=T)
library(hexbin)
set.seed(1234)
x <- rnorm(1e6)
y <- rnorm(1e6)
hbin <- hexbin(
x = x
, y = y
, xbin = 50
, xlab = expression(alpha)
, ylab = expression(beta)
)
## Using plot method for hexbin objects:
plot(hbin, style = "nested.lattice")
abline(h=0)
This seems to generate an S4 object (hbin), which I then plot using plot.
Now I'd like to add a horizontal line to that plot using abline, but unfortunately this gives the error:
plot.new has not yet been called
I have also no idea, how I can manipulate e.g. the position of the axis labels (alpha and beta are within the numbers), change the position of the legend, etc.
I'm familiar with OOP, but so far I could not find out how plot() handles the object (does it call certain methods of the object?) and how I can manipulate the resulting plot.
Why can't I simply draw a line onto the plot?
How can I manipulate axis labels?
Use lattice version of hex bin - hexbinplot(). With panel you can add your line, and with style you can choose different ways of visualizing hexagons. Check help for hexbinplot for more.
library(hexbin)
library(lattice)
x <- rnorm(1e6)
y <- rnorm(1e6)
hexbinplot(x ~ y, aspect = 1, bins=50,
xlab = expression(alpha), ylab = expression(beta),
style = "nested.centroids",
panel = function(...) {
panel.hexbinplot(...)
panel.abline(h=0)
})
hexbin uses grid graphics, not base. There is a similar function, grid.abline, which can draw lines on plots by specifying a slope and intercept, but the co-ordinate system used is confusing:
grid.abline(325,0)
gets approximately what you want, but the intercept here was found by eye.
You will have more luck using ggplot2:
library(ggplot2)
ggplot(data,aes(x=alpha,y=beta)) + geom_hex(bins=10) + geom_hline(yintercept=0.5)
I had a lot of trouble finding a lot of basic plot adjustments (axis ranges, labels, etc.) with the hexbin library but I figured out how to export the points into any other plotting function:
hxb<-hexbin(x=c(-15,-15,75,75),
y=c(-15,-15,75,75),
xbins=12)
hxb#xcm #gives the x co-ordinates of each hex tile
hxb#ycm #gives the y co-ordinates of each hex tile
hxb#count #gives the cell size for each hex tile
points(x=hxb#xcm, y=hxb#ycm, pch=hxb#count)
You can just feed these three vectors into any plotting tool you normally use.. there is the usual tweaking of size scaling, etc. but it's far better than the stubborn hexplot function. The problem I found with the ggplot2 stat_binhex is that I couldn't get the hexes to be different sizes... just different colors.
if you really want hexagons, plotrix has a hexagon drawing function that i think is fine.

Resources