venerdì 14 settembre 2007

Plotting two or more overlapping density plots on the same graph

This post was updated.
See this thread from StackOverflow for other ways to solve this task.

plot.multi.dens <- function(s)
{
junk.x = NULL
junk.y = NULL
for(i in 1:length(s))
{
junk.x = c(junk.x, density(s[[i]])$x)
junk.y = c(junk.y, density(s[[i]])$y)
}
xr <- range(junk.x)
yr <- range(junk.y)
plot(density(s[[1]]), xlim = xr, ylim = yr, main = "")
for(i in 1:length(s))
{
lines(density(s[[i]]), xlim = xr, ylim = yr, col = i)
}
}
#usage:
x = rnorm(1000,0,1)
y = rnorm(1000,0,2)
z = rnorm(1000,2,1.5)
# the input of the following function MUST be a numeric list
plot.multi.dens(list(x,y,z))
library(Hmisc)
le <- largest.empty(x,y,.1,.1)
legend(le,legend=c("x","y","z"), col=(1:3), lwd=2, lty = 1)

9 commenti:

  1. Helpful function, thanks!

    RispondiElimina
  2. Questo commento è stato eliminato dall'autore.

    RispondiElimina
  3. I have run the following command to estimate the density function with legend. But it estimate the density function without legend. why so? could you please answer?

    setwd("c:/mydata")
    getwd()
    setwd("c:/mydata")
    getwd()
    data1<-read.table("MPI_NEW.csv",header=T,sep=",")
    attach(data1)
    names(data1)
    [1] "sn" "MPI_03_04" "MPI_04_05" "MPI_05_06"

    plot.multi.dens <- function(s)
    {
    junk.x = NULL
    junk.y = NULL
    for(i in 1:length(s))
    {
    junk.x = c(junk.x, density(s[[i]])$x)
    junk.y = c(junk.y, density(s[[i]])$y)
    }
    xr <- range(junk.x)
    yr <- range(junk.y)
    plot(density(s[[1]]), xlim = xr, ylim = yr, xlab=" ", main = "MPI")
    for(i in 1:length(s))
    {
    lines(density(s[[i]]), xlim = xr, ylim = yr, col = i)
    }
    }
    x=t(matrix(c(data1$MPI_03_04)))
    y=t(matrix(c(data1$MPI_04_05)))
    z=t(matrix(c(data1$MPI_05_06)))
    plot.multi.dens(list(MPI_03_04,MPI_04_05,MPI_05_06)
    legend(5.8,0.35,legend=c("x","y","z"), col=c(1:3), lty=1)

    RispondiElimina
  4. My guess:
    you have to find appropriate coordinates for the legend. Use the locator(1) function:

    ?locator
    legend(locator(1),legend=c("x","y","z"), col=c(1:3), lty=1)

    And click twice over the desired position on the plot window.

    HTH

    RispondiElimina
  5. Thanks for your continued help, yes, the above command is working fine to locate the legend. Now what if I want to distinguish three density lines not only by color but also by line types (e.g. one density with red color with smooth line, another density with another color with dotted line and the third one ......)

    RispondiElimina
  6. Dear mhc, I suggest you to take a look at the legend manual that you can reach typing:
    ?legend
    For you particular question search for lty parameter.
    An other advice:
    Download and read carefully the manual at this link http://cran.r-project.org/doc/manuals/R-intro.pdf
    HTH

    RispondiElimina
  7. Dear Paolo:
    Thanks for your suggestions. Your function for multi density estimation is interesting. However, one can use the following command to estimate the multi density estimation.
    x = rnorm(1000,0,1)
    y = rnorm(1000,0,2)
    z = rnorm(1000,2,1.5)
    plot(density(x), xlim= c(-4, 6), ylim =c(0, 0.4), col="black", lwd=2, lty=1, xlab=" ", main="Density Estimates for XYZ")
    lines(density(y), xlim= c(-4, 6), ylim =c(0, 0.4), col="red", lwd=2, lty=2, xlab=" ", main="")
    lines(density(z), xlim= c(-4, 6), ylim =c(0, 0.4), col="green", lwd=2, lty=3, xlab=" ", main="")
    legend(locator(1),legend=c("x","y","z"), col=(1:3), lwd=2, lty = 1:3)

    To add legend click twice over the desired position on the graph.

    One can change xlim and ylim depending on their choice of usefulness of the data.

    RispondiElimina
  8. The only advantage of that function, and the main reason it was written, is the fact that you don't need to specify the xlim and ylim for the each vector, the function will take care of the specic ranges automatically.

    RispondiElimina