使用 ggplot 按特定顺序保持图例和 y 轴

Posted

技术标签:

【中文标题】使用 ggplot 按特定顺序保持图例和 y 轴【英文标题】:Keep the legend and y-axis in a specific order with ggplot 【发布时间】:2021-10-05 03:04:13 【问题描述】:

让我们考虑以下数据

analysisdata$question = c("Q1","Q1","Q1","Q2","Q2","Q2","Q3","Q3","Q3","Q4","Q4","Q4")
analysisdata$name = c("G1","G2","G3","G1","G2","G3","G1","G2","G3","G1","G2","G3")
analysisdata$pointEstimate = c(1,2,3,1,2,3,1,2,3,1,2,3)
analysisdata$ci.max = c(2,3,4,2,3,4,2,3,4,2,3,4)
analysisdata$ci.min = c(0,1,2,0,1,2,0,1,2,0,1,2)

以及以下绘图功能:

plotCI <- function(data, ymin = 0, ymax = 1.0, xlab = "XLAB", ylab = "YLAB")
  pd = position_dodge(.6)    ### How much to jitter the points on the plot
  g <- ggplot(data,                ### The data frame to use. 
              aes(x     = factor(y_axis_items),
                  y     = measure,
                  color = factor(legend_factor))) +
    
    geom_point(size  = 2, position = pd) +
    
    geom_errorbar(aes(ymin  = upperBound_CI,
                      ymax  = lowerBound_CI),
                  width = 0.2, 
                  size  = 0.7, 
                  position = pd) +
    coord_flip() +
    scale_y_continuous(limits = c(ymin,ymax)) +
    theme(panel.background = element_rect(fill = 'white', colour = 'white'),axis.title=element_text(size = rel(1.2), colour = "black"),axis.text=element_text(size = rel(1.2), colour = "black"),panel.grid.major = element_line(colour = "#DDDDDD"),panel.grid.major.y = element_blank(), panel.grid.minor.y = element_blank())+ theme(axis.title = element_text(face = "bold")) +
    xlab(xlab)+
    ylab(ylab);
  
  print(g)

如果我调用此代码

dataToPrint <- data.frame(factor(analysisdata$name),factor(analysisdata$question),analysisdata$pointEstimate, analysisdata$ci.max, analysisdata$ci.min)
colnames(dataToPrint) <- c("legend_factor", "y_axis_items","measure", "lowerBound_CI", "upperBound_CI")
plotCI(dataToPrint, xlab="Questions", ylab="", ymax=5)

它给了我下面的图表:

但是,我想在这里做的是尝试将 y 轴上的排序排序不同,比如 G1 在顶部,然后是 G2、G3、G4(但为了有一些可重用的东西再多一点,让我们想象一下只是颠倒字母顺序的解决方案是不行的,我想要一个自定义顺序)。我还希望能够按照图例出现在图表上的顺序对图例进行排序(所以 G3 在此处的顶部)。

我尝试将以下内容添加到我的绘图函数 scale_x_discrete(limits=data$y_axis_item) + 中,但这最终会产生错误类型的图表,并且不能解决我的问题。

有没有人可以解决这个问题。我在这里发现了一些问题,这些问题使用因素来保留数据框中的特定顺序,但是当我的数据框中有重复的 ID 时,这不起作用:

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

要颠倒顺序,您可以使用forcats::fct_rev。要反转图例的顺序,您可以使用guides(color = guide_legend(reverse = TRUE))。如果您想要 y 轴的自定义顺序,这可以通过例如实现。 factor(dataToPrint$y_axis_items, levels = c("Q2", "Q3", "Q1", "Q4"))

library(ggplot2)

colnames(dataToPrint) <- c("y_axis_items", "legend_factor", "measure", "lowerBound_CI", "upperBound_CI")

# Reverse
dataToPrint$y_axis_items <- forcats::fct_rev(dataToPrint$y_axis_items)

plotCI(dataToPrint, xlab = "Questions", ylab = "", ymax = 5) +
  guides(color = guide_legend(reverse = TRUE))

设置自定义订单


dataToPrint$y_axis_items <- factor(dataToPrint$y_axis_items, levels = c("Q2", "Q3", "Q1", "Q4"))

plotCI(dataToPrint, xlab = "Questions", ylab = "", ymax = 5) +
  guides(color = guide_legend(reverse = TRUE))

绘图功能

plotCI <- function(data, ymin = 0, ymax = 1.0, xlab = "XLAB", ylab = "YLAB") 
  pd <- position_dodge(.6) ### How much to jitter the points on the plot
  g <- ggplot(
    data, ### The data frame to use.
    aes(
      x = y_axis_items,
      y = measure,
      color = legend_factor
    )
  ) +
    geom_point(size = 2, position = pd) +
    geom_errorbar(aes(
      ymin = upperBound_CI,
      ymax = lowerBound_CI
    ),
    width = 0.2,
    size = 0.7,
    position = pd
    ) +
    coord_flip() +
    scale_y_continuous(limits = c(ymin, ymax)) +
    theme(panel.background = element_rect(fill = "white", colour = "white"), 
          axis.title = element_text(size = rel(1.2), colour = "black"), 
          axis.text = element_text(size = rel(1.2), colour = "black"), 
          panel.grid.major = element_line(colour = "#DDDDDD"), 
          panel.grid.major.y = element_blank(), panel.grid.minor.y = element_blank()) +
    theme(axis.title = element_text(face = "bold")) +
    xlab(xlab) +
    ylab(ylab)

  g

数据

dataToPrint <- data.frame(
  question = c("Q1", "Q1", "Q1", "Q2", "Q2", "Q2", "Q3", "Q3", "Q3", "Q4", "Q4", "Q4"),
  name = c("G1", "G2", "G3", "G1", "G2", "G3", "G1", "G2", "G3", "G1", "G2", "G3"),
  pointEstimate = c(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3),
  ci.max = c(2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4),
  ci.min = c(0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2)
)

【讨论】:

感谢您提供非常完整的答案。您如何确保您也可以为图例提供定制订单?不只是相反。之后将接受作为答案。不过已经投票了。 与轴项目相同的方法,例如dataToPrint$legend_factor &lt;- factor(dataToPrint$legend_factor, levels = c("G2", "G3", "G1"))。通过guide_legend 进行反转可确保图例项的显示顺序与图中的误差线相同。 "通过 guide_legend 反转确保图例项的出现顺序与图中的误差线相同。"它总是这样吗? 另外,有没有办法始终将其集成到我的绘图功能@stefan 中?所以我不必总是考虑这样做? 嗯。一般来说,这取决于情节的类型,因为reverse=TRUE 只是颠倒了图例项目的顺序。当然可以将代码行 + guides(...) 添加到绘图函数中。

以上是关于使用 ggplot 按特定顺序保持图例和 y 轴的主要内容,如果未能解决你的问题,请参考以下文章

使用 ggplot2 在 R 中保持一致的图形大小(图例和轴改变大小)

ggplot2:重新排序图例中的项目

plotly 和 ggplot 图例顺序交互

ggplot2 - 在大小图例中显示多个键(形状)

ggplot2中散点图的图例(无颜色)

按面板右侧微调ggplot大小和图例位置