Reputation: 861
I have following sample data in R.
d <- read.table(text =
"Grp Var Col1 Col2 Col3
grp_1 8 46.8 50.0 50.6
grp_1 16 95.6 47.4 48.0
grp_1 24 45.1 45.6 46.4
grp_1 32 68.8 44.3 58.2
grp_1 40 44.6 52.2 44.3
grp_1 48 86.5 42.2 68.6
grp_2 40 63.2 95.6 63.0
grp_2 60 66.7 67.5 65.6
grp_2 80 69.6 70.7 67.9
grp_2 100 71.9 73.4 69.3
grp_2 120 73.8 75.7 48.0
grp_3 500 51.9 50.0 50.5
grp_3 1000 65.5 53.0 53.4
grp_3 5000 61.2 99.0 59.9
grp_3 10000 80.1 63.0 62.8
grp_3 30000 25.9 33.8 14.2
", header=T
)
The columns Col1
, Col2
, and Col3
, for each group, need to be plotted against Var.
Group 1 has 6 values each for Var, Col1 - Col3, While groups 2 and 3 have 5 values. I am using Lattice's xyplot()
function to plot them in a grid. The code is below:
#Groups as factors
d$Grp <- factor(d$Grp, levels=c("grp_1","grp_2","grp_3"), order=TRUE)
#Plot the data
xyplot(
Col1 + Col2 + Col3 ~ Var | Grp,
data=d,
superpose=T,
as.table=TRUE,
col=c("#cc0000","#008000", "#0073e6"),
lwd=1.5, ylim = c(0,120),
ylab = list(label=expression("My Values"), fontsize=15),
xlab = list(label="Var",fontsize=15),
key=list(
text = list(c("Col1", "Col2", "Col3")),
lines = list( lwd=1.5, col=c("#cc0000","#008000", "#0073e6")),
corner = c(1, 0),
x = 0.90,
y = 0.17),
par.settings = list(strip.background=list(col="white")),
scales=list(cex=1.2),
type=c("l","g")
)
The plot looks like this:
Clearly, the group 1 and 2 plotted values look messy because x-axis values are 500,1000,5000,10000,30000
instead of 8,16,24,32,40,48
and 40,60,80,100,120
. Is there any way to fix x-axis values for group 1 and 2 using xyplot()
(preferably)? I am also open for other cool suggestions. The expected output could for example be like this:
Upvotes: 1
Views: 2031
Reputation: 813
The plot.trellis
method allows one to plot lattice
objects on a grid. By combining that with update.trellis
method, one can create a layout of arbitrary spacings.
I post this answer (a bit late) to highlight these options in lattice
. My answer also starts in the spirit of the "tidyverse" by creating a long format for the data.
# first update the lattice parameters in 'tp'
library(lattice)
tp <- trellis.par.get() # retrieve all parameters
tp$strip.background$col <- "white"
tp$superpose.line$col <- c("#CC0000","#008000", "#0073E6")
tp$superpose.line$lwd <- 1.5
# data from example already 'd' then convert with simple base functions
myDat <- cbind(d[1:2], stack(d[3:5])) # new variables: "values" & "ind"
# create single plot object
obj <- xyplot(values ~ Var | Grp, df, groups = ind, type = c("g", "l"),
par.settings = tp, scales = list(x = list(relation = "free")),
ylab = "My Values", xlab = "Place holder", as.table = TRUE)
The lattice object (obj
) has the desired format but with only one x-axis label. It can simply be plotted by obj
or plot(obj)
in almost the desired form. However, since it actually is three lattice plots, they can extracted, updated, and plotted in a grid with the update.trellis
and plot.trellis
methods as shown here.
# axis labels and key
xlabs <- paste("My x-axis title", 1:3)
myKey = list(corner = c(5, 0.5), points = FALSE, lines = TRUE)
# assemble final plot
plot(update(o[1], xlab = xlabs[1]), split = c(1,1,2,2), more = TRUE)
plot(update(o[2], xlab = xlabs[2]), split = c(2,1,2,2), more = TRUE)
plot(update(o[3], xlab = xlabs[1], auto.key = myKey),
split = c(1,2,2,2), more = FALSE)
By using
position
option instead of the split
option, one can take finer control over the position of each plot.
Upvotes: 0
Reputation: 46908
You use the scales
option with relation="free"
, I get a plot similar to @Tjebo's above.. not 3 identical plots:
xyplot(
Col1 + Col2 + Col3 ~ Var | Grp,
data=d,
superpose=T,
as.table=TRUE,
col=c("#cc0000","#008000", "#0073e6"),
lwd=1.5, ylim = c(0,120),
ylab = list(label=expression("My Values"), fontsize=15),
xlab = list(label="Var",fontsize=15),
key=list(
text = list(c("Col1", "Col2", "Col3")),
lines = list( lwd=1.5, col=c("#cc0000","#008000", "#0073e6")),
corner = c(1, 0),
x = 0.90,
y = 0.17),
par.settings = list(strip.background=list(col="white")),
scales=list(cex=1.2,x=list(relation="free")),
type=c("l","g")
)
Upvotes: 2
Reputation: 23757
Because you have tagged it ggplot2 as well, here a ggplot2 solution.
I personally think that this is much easier than base plot, but I am incredibly biased.
library(tidyverse)
d_long <-
d %>%
pivot_longer(names_to = "key", values_to = 'value', contains("Col"))
ggplot(d_long, aes(Var, value, color = key)) +
geom_line() +
facet_grid(~Grp, scales = "free_x") +
scale_color_manual(values =c("#cc0000","#008000", "#0073e6"))
Created on 2020-04-28 by the reprex package (v0.3.0)
Upvotes: 1