4

I would like to create plot something like this :

Nether et al

Here we have two variables X = midyear and Y = yearend. I would like to create density plot for each level of X for Y.

I could go to this point, but do not look pretty like what I have in mind particularly angle of the plot and line. Any idea to make such twist or other packages that can do.

set.seed(1234)
m50 <- rnorm(10000, 51, 5)
d50 <- hist(m50, breaks = 100)$density
md50 <- hist(m50, breaks = 100)$mids

m70 <- rnorm(10000, 73, 5)
d70 <- hist(m70, breaks = 100)$density 
md70 <- hist(m70, breaks = 100)$mids

m90 <- rnorm(10000, 90,5)
d90 <- hist(m90, breaks = 100)$density 
md90 <- hist(m90, breaks = 100)$mids

density = c(d50, d70, d90)
yearend = c(md50, md70, md90)
midyear = c(rep(50, length(d50)), rep(70, length(d70)), rep(90, length(d90)))

df <- cbind(midyear, yearend,  density)
require(scatterplot3d)
s3d <- scatterplot3d(df, type = "h", color = "blue",
       angle = 80, scale.y = 0.7, xlim = c(40, 100), 
   zlim = c(0,0.2), pch = ".", main = "Adding elements")

enter image description here

Edits: Using rgl package

require(rgl)
s3d <- plot3d(df, type = "h", 
                     angle = 80, scale.y = 0.7, xlim = c(40, 100), 
                     zlim = c(0,0.15), pch = ".", main = "Adding elements")

enter image description here

jon
  • 11,186
  • 19
  • 80
  • 132

1 Answers1

2

You might be better off with a 2-dimensional graph that will show the distributions without visual distortion. For example, here's a regression line superimposed on a violin plot, so you get both the regression line and the densities on a 2D graph. The code below shows both linear and quadratic polynomial fits to the data:

library(ggplot2)

# Fake data
set.seed(19)
dat = data.frame(yearend=c(rnorm(10000, 51, 6), 
                           rnorm(10000, 60, 5), 
                           rnorm(10000, 75, 5), 
                           rnorm(10000, 85, 4)),
                 midyear = c(rep(51,10000), rep(58,10000), 
                             rep(70,10000), rep(90,10000)))

ggplot(dat, aes(midyear, yearend)) +
  geom_violin(aes(group=midyear)) +
  stat_summary(fun.y=mean, geom="point", colour="red", size=3) +
  geom_smooth(method="lm", se=FALSE) +
  geom_smooth(method="lm", se=FALSE, formula=y~poly(x,2), 
              colour="red", lty=2)

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • thanks for the great alternate idea. I thought one point using boxplot as well but settled with normal curve as this visually appealing (real normal curve) to explain. – jon Sep 05 '15 at 17:13
  • 2
    Appealing, yes. But visually confusing because of the perspective and distortions. A violin plot like the one in this answer is actually way better method of presenting your data than skewed and rotated individual distributions. – Terry Sep 07 '15 at 19:19