uclahs-cds / package-BoutrosLab-plotting-general

Functions to Create Publication-Quality Plots
https://uclahs-cds.github.io/package-BoutrosLab-plotting-general
12 stars 4 forks source link

Adding multiple lines to a plot #173

Closed raagagrawal closed 8 months ago

raagagrawal commented 8 months ago

I am currently trying to add multiple lines to a create.boxplot. I want a line to indicate the median value of a group of measurements (but not the 25th/75th percentiles as in normal boxplot).

I would like to be able to extend the line.func. option such that I can provide an arbitrary number of lines to be drawn on top of the plot. This would allow users to specify that they want the mean or median to be drawn for each group, or any arbitrary percentile.

Toy example:

# create a new dataset with columns 'study.id', 'group', 'length', and 'color'
set.seed(123)
n <- 99
toy.data <- data.frame(
    study.id = rep(1:n, each = 1),
    group = as.factor(rep(1:3, each = n/3)),
    length = rnorm(n, 2, 1),
    color = default.colours(3)[rep(1:3, each = n/3)]
    )

create.boxplot(
    formula = length ~ group,
    data = toy.data,
    main = NULL,
    xlab.label = NULL,
    ylab.label = 'Length (cm)',
    xaxis.cex = 1.2,
    yaxis.cex = 1.2,
    resolution = 50,
    border.col = rgb(1, 1, 1, alpha = 0),
    points.cex = 1,
    add.stripplot = TRUE,
    jitter.amount = 0.15,
    ylimits = c(-0.5,4.5),
    points.col = toy.data$color
    );
raagagrawal commented 8 months ago

Solved!

Please see below a solution that uses panel.segments to add a layer by group.

# create a new dataset with columns 'study.id', 'group', 'length', and 'color'
set.seed(123)
n <- 99
toy.data <- data.frame(
    study.id = rep(1:n, each = 1),
    group = as.factor(rep(1:3, each = n/3)),
    length = rnorm(n, 2, 1),
    color = default.colours(3)[rep(1:3, each = n/3)]
    )

boxplot <- create.boxplot(
    formula = length ~ group,
    data = toy.data,
    main = NULL,
    xlab.label = NULL,
    ylab.label = 'Length (cm)',
    xaxis.cex = 1.2,
    yaxis.cex = 1.2,
    resolution = 50,
    border.col = rgb(1, 1, 1, alpha = 0),
    points.cex = 1,
    add.stripplot = TRUE,
    jitter.amount = 0.15,
    ylimits = c(-0.5,4.5),
    points.col = toy.data$color
    );

medians <- tapply(toy.data$length, toy.data$group, median)

# add segment panel function
addlayer <- layer(
    panel.segments(
        c(0.5,1.5,2.5), 
        medians, 
        c(1.5,2.5,3.5),
        medians
        ), 
    data=toy.data
    )

boxplot <- boxplot + addlayer

print(boxplot)