Ricky
Ricky

Reputation: 4686

Creating a continuous 1d heatmap in R

For lack of a better name, I want to create a continous 1-d heatmap in R, i.e. a 1-d version of this question

Toy data to use:

df <- data.frame(x=1:20,
  freq=c(8, 7, 5, 6, 10, 4, 2, 9, 3, 10, 1, 8, 4, 7, 2, 6, 7, 6, 9, 9))

I can create a crude gridded output using

ggplot(data=df, aes(x=x, y=1)) + geom_tile(aes(fill=freq))

but similar to the other question, I'd like to have a smooth colour transition instead. Unfortunately, I don't understand the 2-d answer well enough to adapt it to 1-d.

Upvotes: 6

Views: 3581

Answers (2)

Axeman
Axeman

Reputation: 35242

Since your data are frequencies, it makes more sense to me to present them as raw data:

df2 <- unlist(apply(df, 1, function(x) rep(x[1], x[2])))

Then I would use the kernel density to create a smooth representation of your categories:

df2 <- density(df2, adjust = 1)
df2 <- data.frame(x = df2$x, y = df2$y) #shouldn't there be an as.data.frame method for this?

And then plot as tiles:

ggplot(df2, aes(x = x, y = 1, fill = y)) + geom_tile()

You can use the adjust argument in the density call to change the level of smoothing.

Adjust 1 (default): plot1 Adjust 0.5: plot2 Adjust 0.3: plot3

Upvotes: 5

PavoDive
PavoDive

Reputation: 6496

I'm not totally sure I understood what you want, but this is an attempt to solve [what I think is] your problem:

First, the vector you have is very short, and the changes on freq are very abrupt, so that will make for a very "tile-like" feeling of the plot. You'll need to address that first. My approach is using a spline interpolation:

 newdf=data.frame(x=spline(df)[[1]],freq=spline(df)[[2]],y=rep(1,times=3*length(df$x)))

Please notice that I also created a y vector in the data frame.

Now it can be plotted using lattice's levelplot:

levelplot(freq~x*y,data=newdf)

Which produces a smoother plot (as I understand, that's what you need). It can be also plotted with ggplot:

ggplot(newdf,aes(x=x,y=y,fill=freq))+geom_tile()

========== EDIT TO ADD ============

Please notice that you can control the new vector length with spline's n argument, making for an even smoother transition (spline(df,n=100)[[1]]) If you follow this option, make sure you adjust the times you repeat 1 in y's definition!!. Default n is 3x the length of the input vector.

Upvotes: 1

Related Questions