【问题标题】:ggplot2: Show category and sub-category for x-axis labelsggplot2:显示 x 轴标签的类别和子类别
【发布时间】:2023-04-06 15:04:02
【问题描述】:
big_theme <- theme(
  panel.background = element_rect(fill = "black"),
  plot.background = element_rect(fill = "black", colour = NA),
  plot.title = element_text(hjust = 0.5, size = 15, color = "white"),
  axis.text.y = element_text(colour = "white", size = 14),
  axis.title.x = element_text(colour = "white", size = 14),
  axis.title.y = element_text(colour = "white", size = 14),
  axis.text.x = element_text(vjust = 1, angle = 45, color = "white", size = 14, hjust=1),
  strip.background = element_rect(fill = "black"),
  strip.text = element_text(colour = 'white'),
  strip.text.y = element_text(angle = 0), 
  legend.position = "top"
)

theme2 = theme(panel.background = element_rect(fill = 'black'),
  legend.background=element_rect(fill = "black"),
  legend.text = element_text(colour = "white", size = 14), 
  legend.justification = "right",
  legend.key.height = unit(1, "line"),
  legend.key = element_rect(color = "black", fill = "black"))

theme3 = theme(plot.background = element_rect(fill = 'black'))

plot1 <- ggplot(sample_data) + big_theme + theme2 + theme3
plot1 + 
  geom_col(position = "identity", 
           aes(x = category, y = value,
               fill = forcats::fct_relevel(variable, c("z", "x", "y")),
               color = forcats::fct_relevel(variable, c("z", "x", "y")))) + 
  scale_fill_manual(values = c("#000000","#D3667C","#53AC79")) + 
  scale_color_manual(values = c("#00A2EF","#D3667C","#53AC79")) + 
  geom_text(aes(label = big_category, x = big_category, y = 0), vjust = 0, 
            size = 3, color = "white", position = position_dodge(width = 1)) +  
  scale_y_continuous(limits = c(0, 2.4), expand = c(0, 0)) 

我有一个如下所示的数据集:

big_category category   variable    value
a     aa    x   1.2
a     ba    x   1.05
a     ca    x   1.11
a     aa    y   1.43
a     ba    y   1.09
a     ca    y   0.97
a     aa    z   1.12
a     ba    z   1.46
a     ca    z   1.32

b     ab    x   1.2
b     bb    x   1.05
b     cb    x   1.11
b     ab    y   1.43
b     bb    y   1.09
b     cb    y   0.97
b     ab    z   1.12
b     bb    z   1.46
b     cb    z   1.32
c     ac    x   1.2
c     ac    y   1.05
c     ac    z   1.11

我希望 x 轴按类别标记,而在 x 轴下方我希望为 big_category 标记。例如,我想要 aa、ba 和 ca 的轴标签,然后是 ggplot 中 big_category a 的一个标签。我不希望它与类别标签混在一起,我还希望它在水平显示的 x 轴标签下方。

我也尝试过 facet_grid 但这给了我一个问题,因为条形的大小不均匀。就像 big_category a 有 3 个类别,而 big_category c 只有 1 个。我希望它们都具有相同的宽度,并且我想要一个连续的图。

更新

big_category category variable value
a aa111111111 x 1.2
a ba111111111 x 1.05
a ca111111111 x 1.11
a aa111111111 y 1.43
a ba111111111 y 1.09
a ca111111111 y 0.97
a aa111111111 z 1.12
a ba111111111 z 1.46
a ca111111111 z 1.32
b ab111111111 x 1.2
b ab111111111 y 1.05
b ab111111111 z 1.11
c ac111111111 x 1.2
c bc111111111 x 1.05
c cc111111111 x 1.11
c ac111111111 y 1.43
c bc111111111 y 1.09
c cc111111111 y 0.97
c ac111111111 z 1.12
c bc111111111 z 1.46
c cc111111111 z 1.32

代码:

big_theme <- theme(
panel.background = element_rect(fill = "black"),
plot.background = element_rect(fill = "black", colour = NA),
plot.title = element_text(hjust = 0.5, size = 15, color = "white"),
axis.text.y = element_text(colour = "white", size = 14),
axis.title.x = element_text(colour = "white", size = 14),
axis.title.y = element_text(colour = "white", size = 14),
axis.text.x = element_text(vjust = 1, angle = 45, color = "white", size = 14, hjust=1),
strip.background = element_rect(fill = "black"),
strip.text = element_text(colour = 'white'),
strip.text.y = element_text(angle = 0),
legend.position = "top"
)

theme2 = theme(panel.background = element_rect(fill = 'black'),
legend.background=element_rect(fill = "black"),
legend.text = element_text(colour = "white", size = 14),
legend.justification = "right",
legend.key.height = unit(1, "line"),
legend.key = element_rect(color = "black", fill = "black"))

theme3 = theme(plot.background = element_rect(fill = 'black'))

ggplot(sample_data %>% mutate(variable=fct_relevel(variable, c("z","x","y")))) +
geom_col(position = "identity",
aes(x = category, y = value, fill = variable, color = variable)) +
facet_grid(. ~ big_category, space="free_x", scales="free_x", switch="x") +
big_theme + theme2 + theme3 +
theme(strip.placement = "outside",
strip.background = element_rect(fill=NA,colour="white"),
panel.spacing.x=unit(0,"cm"),
strip.text = element_text(hjust=0, face="bold", size=12))

【问题讨论】:

  • this SO answer 中的选项 1a 和 1b 可能会有所帮助。基本思想是您按big_category 进行刻面,并将刻面标签放在底部(和轴外)而不是顶部。
  • 我看了看,很有帮助。但是,条形图的大小并不均匀,因为每个 big_category 的类别数量不相等。

标签: r ggplot2


【解决方案1】:

下面是一个示例,使用您的示例数据,说明如何在big_category 中包含category。为了简单起见,我只包含了基本的情节元素。当然,您可以将您的特定主题、颜色和其他元素添加到下面的基本图中。

library(tidyverse)

ggplot(sample_data %>% mutate(variable=fct_relevel(variable, c("z","x","y")))) +
  geom_col(position = "identity", 
           aes(x = category, y = value, fill = variable, color = variable)) + 
  facet_grid(. ~ big_category, space="free_x", scales="free_x", switch="x") +
  theme_classic() +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA, colour="grey50"),
        panel.spacing.x=unit(0,"cm"))

更新:如果我理解您的评论,这里是更新的代码,用于左对齐条形文本并删除条形边框。我不知道一种方法(不破解ggplot之外的底层图形对象)在条带之间只有垂直线。但是,我在面板之间添加了一些空间并添加了面板边框来描绘big_category 级别。

ggplot(sample_data %>% mutate(variable=fct_relevel(variable, c("z","x","y")))) +
  geom_col(position = "identity", 
           aes(x = category, y = value, fill = variable, color = variable)) + 
  facet_grid(. ~ big_category, space="free_x", scales="free_x", switch="x") +
  theme_bw() +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA,colour=NA),
        panel.spacing.x=unit(0.15,"cm"), 
        strip.text = element_text(hjust=0, face="bold", size=12))

更新 2: 我创建了一个带有以下更改的图:(1)big_category x 轴标签左端的标签,以及(2)空白 big_categorycategory 的唯一级别少于 3 个时标记。为了保持与空白标签相同的方面“中断”,我们为每个以前的 big_category 值创建一个唯一的空白字符串(通过改变字符串的长度)。

我不认为情节看起来很好(我实际上认为将big_category 刻面条置于其标准位置并且文本居中会更好),但也许你可以玩弄它并得到满足您需求的东西。我已经评论了代码以解释它在做什么,但如果有什么不清楚的地方请告诉我。

我们将使用您发布的新sample_data,但我们会为big_category 添加第四级:

sample_data = sample_data %>% 
  bind_rows(data_frame(big_category="d",
                       category=c("da1111111111", "db111111"),
                       variable=c("z","x"), value=c(1.1,0.6)))

现在我们将对sample_data 进行一些转换,以将其设置为绘图并将调整后的数据框直接传送到ggplot:

sample_data %>% 
  mutate(variable=fct_relevel(variable, c("z","x","y"))) %>% 
  # Create grouping column (called short_cat) to mark levels of big_category 
  #  with two or fewer unique levels of category
  group_by(big_category) %>% 
  mutate(short_cat = length(unique(category)) <= 2) %>% 
  ungroup %>% 
  # Create a unique white-space string for each unique value of grp
  mutate(grp = c(0, cumsum(diff(short_cat) != 0)),
         grp = sapply(grp, function(g) paste(rep(" ", g), collapse="")),
         # Assign white-space strings to each level of big_category for which short_cat 
         # is TRUE
         big_category=replace(big_category, short_cat, grp[short_cat]),
         # Set factor order for big_category so new levels will stay in same order 
         #  as original levels
         big_category=factor(big_category, levels=unique(big_category))) %>%
  ggplot() +
    geom_col(position = "identity", width=0.8, 
             aes(x = category, y = value, fill = variable, color = variable)) + 
    facet_grid(. ~ big_category, space="free_x", scales="free_x", switch="x") +
    theme_bw() +
    theme(axis.text.x=element_text(angle=45, vjust=1, hjust=1),
          strip.placement = "outside",
          strip.background = element_rect(fill=NA,colour=NA),
          panel.spacing.x=unit(0.15,"cm"), 
          # Left justify big_category labels
          strip.text = element_text(hjust=0, face="bold", size=12)) +
    # Expand left side of x-axis so that big_category labels will be under left 
    #  end of x-axis labels
    expand_limits(x=-0.5)

【讨论】:

  • 如何移动矩形和文本?我希望将 a、b 和 c 向左调整,因为我在 aa、ba、ca、ab、bb、cb、ac 上做了一个just。我想做一个正义,但是当我在文本上做一个正义时,它确实是不可见的,而且我不能只是矩形。我也想在边上放两条线,而不是一个完整的矩形。基本上是没有顶部和底部的矩形。
  • 请查看我的更新答案,如果有帮助请告诉我。
  • 感谢您的更新。我猜这个问题在这个样本数据中没有清楚地显示出来,因为它太小了。但我在类别中有 50 个长标签,我将其调整为 45 度角。因此,标签很好地位于图表的左侧。我希望大类别标签一直到标签的左下角。另外,我希望能够删除少于 2 个类别的 big_categories 的 big_category 标签。我已更新代码和图表以反映此更改和问题
猜你喜欢
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多