Search code examples
rplotgraphweighted

How to keep equal relative sizes of points in a graph?


I want to make a graph where the size of the circles indicate the size of the sample. if i use plot in p1(), it works fine.

but if i try to have the different type of points colored, then the relative size is wrong.

How would I get both the red and green circles to be the same size?

p1<-function() {
    plot(t$x,t$y,cex=100*t$size,xlim=c(0,1),ylim=c(0.,1.))    
}
p2<-function() {
    plot(t$x[t$r=="0"],t$y[t$r=="0"],xlim=c(0,1),ylim=c(0.,1.),cex=100*t$size,col="red")
    points(t$x[t$r=="1"],t$y[t$r=="1"],xlim=c(0,1),ylim=c(0.,1.),cex=100*t$size,col="green")
}
l<-20
x<-seq(0,1,1/l)
y<-sqrt(x)
r=round(runif(n=length(x),min=0,max=.8))
n<-1:length(x)
size=n/sum(n)
t<-data.frame(x,y,r,n,size)
t$r<-factor(r)
str(t)
p1()

Solution

  • You have to change function p2 a bit. You are using t$size, all of it, when you should be subsetting by the factor t$r, since you are doing so when plotting the points.

    If you plot t$x[t$r == "0"] versus t$y[t$r == "0"] then you must use the sizes corresponding to those points, which are t$size[t$r == "0"]. Alternatively, you could subset the data frame t first, and then use those two resulting data frames to plot the points. See function p2_alt at the end.

    p2 <- function() {
      plot(t$x[t$r == "0"], t$y[t$r == "0"],
           xlim = c(0, 1), ylim = c(0., 1.),
           cex = 100*t$size[t$r == "0"],
           col = "red",
           xlab = "x", ylab = "y")
      points(t$x[t$r == "1"],
             t$y[t$r == "1"],
             xlim = c(0, 1), ylim = c(0., 1.),
             cex = 100*t$size[t$r == "1"],
             col = "green")
    }
    
    set.seed(651)    # make the results reproducible
    
    l <- 20
    x <- seq(0, 1, 1/l)
    y <- sqrt(x)
    r <- round(runif(n = length(x), min = 0, max = 0.8))
    n <- 1:length(x)
    size <- n/sum(n)
    t <- data.frame(x, y, r, n, size)
    t$r <- factor(r)
    #str(t)
    #p1()
    p2()
    

    graph relative points size

    p2_alt <- function() {
      df1 <- subset(t, r == "0")
      df2 <- subset(t, r == "1")
      plot(df1$x, df1$y,
           xlim = c(0, 1), ylim = c(0., 1.),
           cex = 100*df1$size,
           col = "red",
           xlab = "x", ylab = "y")
      points(df2$x,
             df2$y,
             xlim = c(0, 1), ylim = c(0., 1.),
             cex = 100*df2$size,
             col = "green")
    }
    
    p2_alt()
    

    The graph is exactly the same, but maybe the code is more readable.

    Finally, note that I have added arguments xlab and ylab to both p2() and p2_alt().