Say I want to plot some data where I know I ought to have some values, but I don't. E.g., some value for all the atoms in a period on the periodic table, but a couple atoms are missing. I want to indicate that the values are missing by including their locations on the x-axis, but NOT showing an (x,y) point at those x values.
How do I set up a scale_*_discrete so that the labels for the missing atoms are still shown?
The data we want to plot
vals <- seq(1.1:11.1)
shortlist <- c("Ce","Pr","Nd","Sm","Gd","Tb","Dy","Ho","Er","Tm","Yb")
radii <- c(1.010,0.990,0.983,0.958,0.938,0.923,0.912,0.901,0.890,0.880,0.868)
df<-do.call(rbind, Map(data.frame, shortlist=shortlist,radii=radii,vals=vals))
#lists for labels with extra atoms
lims <- c(1.032,1.010,0.990,0.983,0.97,0.958,0.947,0.938,0.923,0.912,0.901,0.890,0.880,0.868,0.861)
labs<-c("La","Ce","Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm","Yb","Lu")
#Why does it not include all the values in 'lims'?
ggplot(data=df) +
geom_point(aes(x=factor(radii), y=vals)) +
scale_x_discrete(breaks = lims, labels=labs)
Bonus points if the lims
are spaced accurately (i.e. La=1.032 and Ce=1.010 are further apart than Yb=0.868 and Lu=0.861). Is scale_x_discrete even the right tool to do this?
If you don't want even spacing, then you don't want a discrete scale. While you could use the breaks
, labels
, and limits
arguments separately, I'd do it all with a named vector:
my_breaks = setNames(lims, nm = labs) |> sort()
ggplot(data=df) +
geom_point(aes(x = radii, y = vals)) +
scale_x_continuous(breaks = my_breaks, limits = range(my_breaks)) +
theme(panel.grid.minor.x = element_blank())
An evenly-spaced version with a discrete scale:
ggplot(data=df) +
geom_point(aes(x = shortlist, y = vals)) +
scale_x_discrete(limits = labs)