rggplot2axis-labels

Why does scale_*_discrete not show all the labels provided?


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?

enter image description here

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?


Solution

  • 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())
    

    enter image description here

    An evenly-spaced version with a discrete scale:

    ggplot(data=df) + 
      geom_point(aes(x = shortlist, y = vals)) +
      scale_x_discrete(limits = labs)
    

    enter image description here