Tiled xyplots, how to colour independently to mimic levelplot map? - r

I am trying to plot several lines using the lattice package to produce a tiled figure. Here is an example (which is wrong, see bellow):
(source: ubuntuone.com)
I would like to mimic this one (in terms of the colour pattern) :
(source: ubuntuone.com)
Both plots are colouring the same variable "subset$speed1DaboveT". The first is done with xyplot the second with levelplot.
My problem is that the one with the curves is not colouring correctly, possibly because i am asking the wrong thing. I have followed this example from another question (which, importantly, is a single figure):
dfrm <- data.frame( y=c(rnorm(10),rnorm(10)),
x=1:10,
grp=rep(c("a","b"),each=10))
xyplot(y~x, group=grp, type="l", data=dfrm, col=c("red","blue"))
By doing:
keys=unique(subset$speed1DaboveT)
theseCol= colF(length(keys))
pp= xyplot( freq~patch|B+G
,data=subset
,scales=list( x=list(cex=0.5), y=list(cex=0.5,lim=c(0,1.1)) )
,strip = FALSE
,t='l'
,group=speed1DaboveT
,col=theseCol
,lwd=2
,cex=0.5
,panel = function(x, y, col, ...) {
panel.xyplot(x, y, col=col, ...)
}
)
In my case i am using 2 factors (B and G) and the example has none. This may mean that the colours given to xyplot should perhaps follow a different order? Anyone knows how to?

So, i failed to notice that the range would not be the same. Sorry for the question, things were solved once i forced the colour range of the xyplot to be the same as the levelplot, that is [0,0.16]
thanks

Related

R plot overlay barplot with plot type "p" (confused with factors)

I'm new to R. Previously, I've been able to overlay 2 separate plots that were of the same kind, p1 and p2, using plot (p1); plot (p2, add=T).
I'm struggling with the definition of factors when overlaying a barplot with a point plot showing all individual points.
I can individually plot the barplot as I want it. The point plot looks like I want it, but I realize I'm using an incorrect definition of phase as numerical to force R plot to display each value, rather than default to a boxplot (like when I use plot(my.df$cond, my.df$val).
Any tips on defining my variable types correctly or whether I'm using the correct barplot and plot functions, would be greatly appreciated. Thank you so much.
shpad <- c(1,2,5,6,1,2,5,6,1,2,5,6,1,2,5,6)
my.df <- data.frame(val=c(0.0738,0.0518,0.002,0.0397,0.1452,0.1152,0.1774,0.0658,0.0218,0.0497,-0.0296,0.0653,0.0848,0.1296,0.1416,0.0923,
phase=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4),
sub=c(1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4),
cond=c("NsNm", "NsNm", "NsNm", "NsNm", "NsLm", "NsLm", "NsLm", "NsLm", "LsNm", "LsNm", "LsNm", "LsNm", "LsLm", "LsLm", "LsLm", "LsLm"))
avg <-tapply(my.df$val, my.df$phase, mean)
barplot(avg, border=NA, names.arg=c("NsNm", "NsLm", "LsNm", "LsLm"),col=c("blue","darkblue","red", "darkred"),ylab = "score",ylim=c(-0.03,0.25))
plot(my.df$phase, my.df$val, type="p", ylim=c(-0.03,0.25), ylab = "score", pch=shpad)
tl;dr: problem is that if instead of the last line, I have plot(my.df$phase, my.df$val, type="p", ylim=c(-0.03,0.25), ylab = "score", pch=shpad, add=T), the formats are incongruent.
Alright, so, I've tried for a bit to accomplish what you wanted, but the best I could do with the base plotting system is this:
Which is accomplished purely by your lines of code above except for the last line, which I replaced with
points(my.df$phase,my.df$val,type="p",pch=shpad)
However, I think you can do much better, if you want to keep the same kind of plot, using the ggplot2 library. Using this code:
library('ggplot2')
new.df <- data.frame(avg,phase=levels(factor(phase)))
ggplot(new.df) +
geom_bar(stat="identity",aes(x=levels(phase),y=avg, fill=c("NsNm","NsLm","LsNm","LsLm")))+
geom_point(aes(x=my.df$phase,y=my.df$val,shape=factor(shpad))) +
scale_x_discrete(name="Type",labels=c("NsNm","NsLm","LsNm","LsLm")) +
ylab("Score")
you can make this chart:
I didn't adjust the coloring and the point types and the legend titles (not sure how important they are, but those can be fiddled with). However, you can see this probably produces the result you were aiming for.

Add points to pairs plot?

Is there any way for me to add some points to a pairs plot?
For example, I can plot the Iris dataset with pairs(iris[1:4]), but I wanted to execute a clustering method (for example, kmeans) over this dataset and plot its resulting centroids on the plot I already had.
It would help too if there's a way to plot the whole data and the centroids together in a single pairs plot in such a way that the centroids can be plotted in a different way. The idea is, I plot pairs(rbind(iris[1:4],centers) (where centers are the three centroids' data) but plotting the three last elements of this matrix in a different way, like changing cex or pch. Is it possible?
You give the solution yourself in the last paragraph of your question. Yes, you can use pch and col in the pairs function.
pairs(rbind(iris[1:4], kmeans(iris[1:4],3)$centers),
pch=rep(c(1,2), c(nrow(iris), 3)),
col=rep(c(1,2), c(nrow(iris), 3)))
Another option is to use panel function:
cl <- kmeans(iris[1:4],3)
idx <- subset(expand.grid(x=1:4,y=1:4),x!=y)
i <- 1
pairs(iris[1:4],bg=cl$cluster,pch=21,
panel=function(x, y,bg, ...) {
points(x, y, pch=21,bg=bg)
points(cl$center[,idx[i,'x']],cl$center[,idx[i,'y']],
cex=4,pch=10,col='blue')
i <<- i +1
})
But I think it is safer and easier to use lattice splom function. The legend is also automatically generated.
cl <- kmeans(iris[1:4],3)
library(lattice)
splom(iris[1:4],groups=cl$cluster,pch=21,
panel=function(x, y,i,j,groups, ...) {
panel.points(x, y, pch=21,col=groups)
panel.points(cl$center[,j],cl$center[,i],
pch=10,col='blue')
},auto.key=TRUE)

How to get shaded background in xyplot in R?

using xyplot from the lattice package, I plot a time series over a number of years. I would to add a shaded area for some of these years to indicate that this time period was "special" (e.g. war).
Please apologize if this is trivial, but I could not figure out how to do that, so I would be happy if someone could help me out, or at least point me in the right direction. I think my main problem is that I don't really know how to approach this problem. I am still relatively new to R, and to lattice in particular.
Here a minimal example:
xyplot( rnorm(100) ~ 1:100, type="l", col="black")
In the corresponding plot, I would like the color of the background (from say x-values of 45 until 65) from the bottom to the top of the plotting area be shaded in, say, light grey.
Note that solutions that I have found so far use base graphics and the polygon-function, but there the intention is to shade the area under or above a curve, which is different from what I would like to do. I don't "just" want to shade the area below my line, or above my line. Instead I would like to shade the entire background for a given time interval.
If anyone could help me out here, I would be very grateful!
See ?panel.xblocks in the latticeExtra package:
library(latticeExtra)
x <- 1:100
xyplot( rnorm(100) ~ x, type="l", col="black") +
layer_(panel.xblocks(x, x > 20, col = "lightgrey"))
Try this:
xyplot(
rnorm(100) ~ 1:100, type="l", col="black",
panel=function (x,y,...){
panel.rect(xleft=45, xright=65,ybottom=-3, ytop=3,col="grey")
panel.xyplot(x,y,...)
}
)
The panel.rect() function controls the rectangle and is the lattice equivalent of the rect() function. It has a variety of settings that you may find useful. It is called first and then the xyplot() is put on top of it. You many need to play around a little to get your ybottom and ytop parameters to look as you like them.
trellis.focus("panel", 1, 1)
grid.rect(x =.55, , y=.5, w = .2, height=6,
gp = gpar(fill = "light grey"))
trellis.unfocus()
This differs from #JohnPaul's solution in a couple of ways (and I think his answer is better). This uses the center of the desired X-band for placement in "native coordinates" and calculates the width as 'range(xlim)/range(band)' and it modifies an existing plot. the grid.rect function is the grid packages lower level function that is used by panel.rect. I sometimes find this useful when integrating lattice panels inside the xyplot system defeats me.

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.

R: Plotting one ECDF on top of another in different colors

I have a couple of cumulative empirical density functions which I would like to plot on top of each other in order to illustrate differences in the two curves. As was pointed out in a previous question, the function to draw the ECDF is simply plot(Ecdf()) And as I read the fine manual page, I determined that I can plot multiple ECDFs on top of each other using something like the following:
require( Hmisc )
set.seed(3)
g <- c(rep(1, 20), rep(2, 20))
Ecdf(c( rnorm(20), rnorm(20)), group=g)
However my curves sometimes overlap a bit and can be hard to tell which is which, just like the example above which produces this graph:
I would really like to make the color of these two CDFs different. I can't figure out how to do that, however. Any tips?
If memory serves, I have done this in the past. As I recall, you needed to trick it as Ecdf() is so darn paramterised. I think in help(ecdf) it hints that it is just a plot of stepfunctions, so you could estimate two or more ecdfs, plot one and then annotate via lines().
Edit Turns out it is as easy as
R> Ecdf(c(rnorm(20), rnorm(20)), group=g, col=c('blue', 'orange'))
as the help page clearly states the col= argument. But I have also found some scriptlets where I used plot.stepfun() explicitly.
You can add each curve one at a time (each with its own style), e.g.
Ecdf(rnorm(20), lwd = 2)
Ecdf(rnorm(20),add = TRUE, col = 'red', lty = 1)
Without using Ecdf (doesn't look like Hmisc is available):
set.seed(3)
mat <- cbind(rnorm(20), rnorm(20))
matplot(apply(mat, 2, sort), seq(20)/20, type='s')

Resources