Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I scale symbol size by a data attribute in R lattice?

Tags:

r

lattice

I would like to scale symbol size by a data attribute using Lattice. In the example, I am conditioning on Month. There are two groups ('Ellipse'), each has three x-y observations made at Hours 1,2, and 3. It's a point & line graph, and I want to make the symbols for each Ellipse increment in size according to Hour, to indicate the direction in which time is incrementing. In the xyplot code below, I have added 'cex=d$Hour', but this just assigns different symbol sizes to the two Ellipses.

d <- data.table(expand.grid(Hour=1:3, Month=1:3, Ellipse=1:2))
d[, x := c(rnorm(9, mean=1, sd=1),rnorm(9, mean=2, sd=1.5))]
d[, y := c(rnorm(9, mean=1, sd=1),rnorm(9, mean=2, sd=2))]

xyplot(y ~ x|Month, d, type=c('l','p'), group = Ellipse,
    cex = d$Hour,
    auto.key=list(title="Ellipse", corner=c(0.8,0.8)))

Example showing symbol size scaled by Ellipse instead of Hour

like image 238
Seth W. Bigelow Avatar asked Dec 01 '25 16:12

Seth W. Bigelow


1 Answers

The default panel function for xyplot is panel.xyplot, which calls panel.superpose when argument groups is non-NULL.

So we read help("panel.superpose"):

panel.superpose divides up the x (and optionally y) variable(s) by the unique values of groups[subscripts], and plots each subset with different graphical parameters. The graphical parameters (col.symbol, pch, etc.) are usually supplied as suitable atomic vectors, but can also be lists. When panel.groups is called for the i-th level of groups, the corresponding element of each graphical parameter is passed to it. In the list form, the individual components can themselves be vectors.

So we try the "list form" of graphical parameter cex:

library(lattice)
set.seed(0L)

d <- expand.grid(Hour = 1:3, Month = 1:3, Ellipse = 1:2)
d[["x"]] <- c(rnorm(9, mean = 1, sd = 1), rnorm(9, mean = 2, sd = 1.5))
d[["y"]] <- c(rnorm(9, mean = 1, sd = 1), rnorm(9, mean = 2, sd = 2  ))

xyplot(y ~ x | Month,
       data = d,
       auto.key = list(title = "Ellipse", corner = c(0.8, 0.8)),
       groups = Ellipse,
       type = c("l", "p"), 
       cex = list(sort(unique(d[["Hour"]]))))

And that seems to do the trick ...

same image but with points increasing in size within groups

Well, in general, Hour need not be 1:3 in every level of Month:Ellipse. In the general case, you may need to use other features of lattice to get what you want, e.g., you may need to define your own panel function wrapping panel.xyplot. But that seems to be beyond the scope of the question ...

like image 101
Mikael Jagan Avatar answered Dec 03 '25 08:12

Mikael Jagan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!