简体   繁体   中英

ggplot facet_wrap with equally spaced axes

Say I have the following dummy data frame:

df <- data.frame(let = LETTERS[1:13], value = sample(13), 
group = rep(c("foo", "bar"), times = c(5,8)))

df
  let value group
1    A     2   foo
2    B     1   foo
3    C    12   foo
4    D     8   foo
5    E     4   foo
6    F    13   bar
7    G    11   bar
8    H     3   bar
9    I     7   bar
10   J     5   bar
11   K    10   bar
12   L     9   bar
13   M     6   bar

Using ggplot with facet_wrap allows me to make a panel for each of the groups...

library(ggplot2)
ggplot(df, aes(x= let, y = value)) + 
geom_point() + 
coord_flip() +
facet_wrap(~group, scales = "free")

在此处输入图片说明

..but the vertical axes are not equally spaced, ie the left plot contains more vertical ticks than the right one. I would like to fill up the right vertical axis with (unlabeled) ticks (with no plotted values). In this case that would add 3 empty ticks, but it should be scalable to any df size.

What is the best way to accomplish this? Should I change the data frame, or is there a way to do this using ggplot?

A cludgy solution that requires magrittr (for the compound assignment pipe %<>% ):

df %<>% 
  rbind(data.frame(let = c(" ", "  ", "   "), 
                   value = NA, 
                   group = "foo"))

在此处输入图片说明

I just add three more entries for foo that are blank strings (ie, just spaces) of different lengths. There must be a more elegant solution, though.

I'm not sure why you want to arrange the categorical variable on your chart as you do other than aesthetics (it does seem to look better). At any rate, a simple workaround which seems to handle general cases is to note that ggplot uses a numerical scale to plot categorical variables. The workaround for your chart is then for each x value to plot a transparent point at the y value equal to the number of categorical variables. Points are plotted for all x values as a simple solution to the case of non-overlapping ranges of x values for each group. I've added another group to your data frame to make the example a bit more general.

library(ggplot2)
set.seed(123)
df <- data.frame(let = LETTERS[1:19], value = c(sample(13),20+sample(6)), 
             group = rep(c("foo", "bar", "bar2"), times = c(5,8,6)))
num_rows <- xtabs(~ group, df)
max_rows <- max(num_rows)

sp <- ggplot(df, aes(y= let, x = value)) + 
      geom_point() + 
      geom_point(aes(y = max_rows +.5), alpha=0 ) +
      facet_wrap(~group, scales = "free", nrow=1 )
plot(sp)

This gives the following chart: 在此处输入图片说明

Use free_x instead of free , like this:

ggplot(df, aes(x= let, y = value)) + 
  geom_point() + 
  coord_flip() +
  facet_wrap(~group, scales = "free_x")+
  theme(axis.text.y=element_blank(),
        axis.ticks.y=element_blank())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM