Universal scale bar for paneled levelplots - r

I would like to have multiple heatmaps/levelplots in a single plot, with a universal scale bar. I have the plots arranged, and I think I'm close to the answer, but I want to make sure I don't mess the scale up.
#Fake data
library(gridExtra)
fill = rnorm(100,4)
matA = matrix(fill, ncol=10)
matB = matrix(fill * 2, ncol=10)
# Plotting
a=levelplot(matA, colorkey=FALSE)
b=levelplot(matB, colorkey=list(col=rainbow(1000), at=seq(0,6, length.out=1000)))
grid.arrange(a,b,ncol=2)
Thanks for any help!

Instead of using grid.arrange, you may rearrange your data to be able to use the formula method of x in levelplot. This allows you to easily create a plot with different panels based on a grouping variable g, with a common scale. Here g ('L1') corresponds to the different matrices.
library(reshape2)
library(lattice)
# put your matrices in a list an melt them to one data frame.
l <- list(matA, matB)
df <- melt(l)
# plot
levelplot(value ~ Var1 * Var2 | L1, data = df,
col.regions = rainbow(100))

Related

How to make a single plot from two dataframes with ggplot2

I have 2 datasets, called A and B.
I want to compare the distribution of one common variable, called k, showing up in both dataset, but of different lengths (A contains 2000 values of k, while B has 1000, both have some N/A). So I would like to plot the distribution of A$k anf B$k in the same plot.
I have tried:
g1 <- ggplot(A, aes(x=A$k)) + geom_density()
g2 <- ggplot(B, aes(x=B$k)) + geom_density()
g <- g1 + g2
But then comes the error:
Don't know how to add o to a plot.
How can I overcome this problem?
Since we dont have any data it is hard to provide a specific solution that meets your scenario. But below is a general principal of what I think you trying to do.
The trick is to put your data together and have another column that identifies group A and group B. This is then used in the aes() argument in ggplot. Bearing in mind that combining your data frames might not be as simple as what I have done since you might have some extra columns etc.
# generating some pseudo data from a poisson distribution
A <- data.frame(k = rpois(2000, 4))
B <- data.frame(k = rpois(1000, 7))
# Create identifier
A$id <- "A"
B$id <- "B"
A_B <- rbind(A, B)
g <- ggplot(data = A_B, aes(x = k,
group = id, colour = id, fill = id)) + # fill/colour aes is not required
geom_density(alpha = 0.6) # alpha for some special effects
g
I can't tell you exactly that to do without knowing what data sets actually look like. But merging data sets into one then use ggplot() by specifying group or 'colour' would be one way to compare.
Another way is to use grid.arrange() from gridExtra package.
gridExtra::grid.arrange(g1, g2)
This is really easy and pretty convenient function. If you want to know more about gridExtra package, visit this official document.

faceting by unique pairs

I would like to create some plots with ggplot using faceting. I'm relatively new to ggplot so I'm struggeling setting up the plot. For testing I set up some test data. The actual data is huge and I want first to play around with these toy case. Here is the toy data
m1 <- matrix(rep(c("Skin","Human"),100),ncol = 2,byrow = T)
m2 <- matrix(rep(c("Head","Animal"),200),ncol = 2, byrow=T)
m3 <- matrix(rep(c("Skin","Animal"),250), ncol = 2, byrow=T)
y <- rnorm(550,0,1)
x1 <- rnorm(100,0,1)
x2 <- rnorm(200,0,1)
x3 <- rnorm(250,0,1)
m1 <- as.data.frame(cbind(x1,m1))
m2 <- as.data.frame(cbind(x2,m2))
m3 <- as.data.frame(cbind(x3,m3))
colnames(m1) <- c("x1","type","class")
colnames(m2) <- c("x1","type","class")
colnames(m3) <- c("x1","type","class")
data <- as.data.frame(cbind(y,rbind(m1,m2,m3)))
data <- cbind(data,rnorm(550,0,1))
colnames(data) <- c("y","x1","type","class","x2")
data <- data[,c("y","x1","x2","type","class")]
plot(sort(data[1:100,"y"]),sort(data[1:100,"x1"]),col="red")
points(sort(data[1:100,"y"]),sort(data[1:100,"x2"]),col="blue")
I would like to have a plot for all unique pairs of c("type","class") where in each plot I see two scatterplots of x1 and x2 against y. I thought facetting is the right approach, however I'm struggeling to achieve the desired result.
Based on the plots that your sample code generates, it seems like you want to plot two sets of points (x1,y) and (x2,y) on the same plot, which ggplot is able to handle well. However, ggplot works well with long tables rather than wide ones.
I've provided one way to achieve your desired outcome. The following steps can be performed after your chunk of code to achieve the desired outcome.
Melt your table wide-to-long make use of ggplot's in-built functionality. Note that the color argument automatically plots the x1 and x2 in different colors.
library(reshape2) # Used to melt the table
library(ggplot2) # Used to plot
data <- melt(data, id.vars = c('type','class','y'), measure.vars = c('x1','x2'))
head(data)
# type class y variable value
# 1 Skin Human 1.3170057 x1 -1.09101346133313
# 2 Skin Human 1.2805021 x1 -0.883308758331181
# 3 Skin Human -0.7620298 x1 0.0800447346341697
# 4 Skin Human 0.2766297 x1 0.589741587886533
# 5 Skin Human -1.8504755 x1 -0.178520217862402
# 6 Skin Human 0.6474738 x1 0.1039386636512
p1 <- ggplot(data, aes(x = as.numeric(value), y = y, color = variable))
print(p1)
Using facet_wrap to facet by unique combinations of type and class
faceted <- p1 + facet_wrap(~type + class)
print(faceted)

R violin plot overlay 2 dataframes

Say you have two dataframes
M1 <- data.frame(sample(1:3, 500, replace = TRUE), ncol = 5)
M2 <- data.frame(sample(1:3, 500, replace = TRUE), ncol = 5)
and I want to overlay them as violin plots as seen here:
Overlay violin plots ggplot2
but I have 2 dataframes like above (but bigger) not one with 3 columns as in the example above
I have tried the advice using melt as seen here:
Violin plot of a data frame
but I cant get it to overlay two dataframes
help is much appreciated:
Like this?
library(ggplot2)
library(reshape2)
set.seed(1)
M1 <- data.frame(matrix(sample(1:5, 500, replace = TRUE), ncol = 5))
M2 <- data.frame(matrix(sample(2:4, 500, replace = TRUE), ncol = 5))
M1.melt <- melt(M1)
M2.melt <- melt(M2)
ggplot() +
geom_violin(data=M1.melt, aes(x=variable,y=value),fill="lightblue",colour="blue")+
geom_violin(data=M2.melt, aes(x=variable,y=value),fill="lightgreen",colour="green")
There are several issues. First, data.frame(...) does no take an ncol argument, so your code just generates a pair of 2-column data frames with the second column called ncol with all values = 5. If you want 5 columns (do you??) then you have to use matrix(...) as above.
Second, you do need to use melt(...) to reorganize the dataframes from "wide" format (categories in 5 different columns) to "long" format (all data in 1 column, called value, with categories distinguihsed by a second column, called variable).
Another way to do this combines the two dataframes first:
M3 <- rbind(M1,M2)
M3$group <- rep(c("A","B"),each=100)
M3.melt <- melt(M3, id="group")
ggplot(M3.melt, aes(x=variable, y=value, fill=group)) +
geom_violin(position="identity")
Note that this generates a slightly different plot because ggplot scales the width of the violins together, whereas in the earlier plot they were scaled separately.
EDIT (Response to OP's comment)
To put the fill colors in a legend, you have to make them part of an aesthetic scale: put fill=... inside the call to aes(...) as follows.
ggplot() +
geom_violin(data=M1.melt, aes(x=variable,y=value,fill="M1"),colour="blue")+
geom_violin(data=M2.melt, aes(x=variable,y=value,fill="M2"),colour="green")+
scale_fill_manual(name="Data Set",values=c(M1="lightblue",M2="lightgreen"))

R: Loop pairs of columns in a dataframe

Is it possible to plot pairs of columns in a single plot with a loop? For example, if I have a data frame of time series with 10 columns (x1, x2.. x10), I would like to create 5 plots: 1st plot will display x1 and x2, the 2nd plot would display x3 and x4 and so on.
Any plotting method would be useful, (zoo, lattice, ggplot2).
I got stuck at creating a loop to plot a single variable:
set.seed(1)
x<- data.frame(replicate(10,rnorm(10, mean = 0, sd = 1)))
cols <- seq(1,10)
library(zoo)
z <- read.zoo(x)
for (i in cols) {
plot(z[,i], screen = 1)
}
Thanks in advance.
How about this with ggplot2 and reshape2:
require(reshape2)
require(ggplot2)
m<-melt(matrix(z,10))
m$facet<-cut(m$Var2,c(0,2,4,6,8,10))
ggplot(m)+geom_line(aes(x=Var1,y=value,group=Var2,color=factor(Var2)))+facet_wrap(~ facet)
It can be done in a single line without a loop like this where the col argument specifies that the odd series are black and the even are red. Note that z in the question has 9 columns (since the first column in x is the time index) so we have used a 10 column z below instead which was likely what was intended.
library(zoo)
# test data
set.seed(123); z <- zoo(matrix(rnorm(250), 25)); colnames(z) <- make.names(1:10)
plot(z, screen = rep(colnames(z)[c(TRUE, FALSE)], each = 2), col = 1:2)
The output is shown below. To produce a single column add the argument nc=1 or to produce a lattice plot replace plot with xyplot.
ADDED: lattice solution.
like this? Although I am not clear how you want to plot it.
par(mfrow=c(1,5))
for (i in seq(1,10,by=2)){
plot(x[,i],x[,i+1])
}

Combine continuous and discrete color scale in ggplot2?

I am a ggplot2 newbie. I am making a scatter plot where the points are colored based on a third continuous variable. However, for some of the points, that continuous variable has either an Inf value or a NaN. How can I generate a continuous scale that has a special, separate color for Inf and another separate color for NaN?
One way to get this behavior is to subset the data, and make a separate layer for the special points, where the color is set. But I'd like the special colors to enter the legend as well, and think it would be cleaner to eliminate the need to subset the data.
Thanks!
Uri
I'm sure this can be made more efficient, but here's one approach. Essentially, we follow your advice of subsetting the data into the different parts, divide the continuous data into discrete bins, then patch everything back together and use a scale of our own choosing.
library(ggplot2)
library(RColorBrewer)
#Sample data
dat <- data.frame(x = rnorm(100), y = rnorm(100), z = rnorm(100))
dat[sample(nrow(dat), 5), 3] <- NA
dat[sample(nrow(dat), 5), 3] <- Inf
#Subset out the real values
dat.good <- dat[!(is.na(dat$z)) & is.finite(dat$z) ,]
#Create 6 breaks for them
dat.good$col <- cut(dat.good$z, 6)
#Grab the bad ones
dat.bad <- dat[is.na(dat$z) | is.infinite(dat$z) ,]
dat.bad$col <- as.character(dat.bad$z)
#Rbind them back together
dat.plot <- rbind(dat.good, dat.bad)
#Make your own scale with RColorBrewer
yourScale <- c(brewer.pal(6, "Blues"), "red","green")
ggplot(dat.plot, aes(x,y, colour = col)) +
geom_point() +
scale_colour_manual("Intensity", values = yourScale)

Resources