【问题标题】:Custom spacing between x axis labels in ggplotggplot中x轴标签之间的自定义间距
【发布时间】:2023-03-06 08:34:01
【问题描述】:

我有一个 df:

   Year          Ratio       N    Mean        sd        se        ci
97  1867 TILLBANK...PLACTILL 2  3.861999  4.082170  2.886530  36.67685
98  1867   TILLOBL..PLACTILL 2 21.848833 17.859532 12.628596 160.46153
99  1867   TILLLOAN.PLACTILL 2 54.197044 23.309360 16.482207 209.42629
100 1867   TILLEQUI.PLACTILL 2  0.000000  0.000000  0.000000   0.00000
101 1867   TILLCONT.PLACTILL 2  0.000000  0.000000  0.000000   0.00000
102 1867   TILLRECI.PLACTILL 2 10.772286  5.110514  3.613679  45.91615


str(df) :

     'data.frame':  1152 obs. of  7 variables:
 $ Year : Factor w/ 156 levels "1855","1856",..: 13 13 13 13 13 13 13 13 14 14 ...
 $ Ratio: Factor w/ 8 levels "TILLBANK...PLACTILL",..: 1 2 3 4 5 6 7 8 1 2 ...
 $ N    : num  2 2 2 2 2 2 2 2 2 2 ...
 $ Mean : num  3.86 21.85 54.2 0 0 ...
 $ sd   : num  4.08 17.86 23.31 0 0 ...
 $ se   : num  2.89 12.63 16.48 0 0 ...
 $ ci   : num  36.7 160.5 209.4 0 0 ...

1) 我正在做一个ggplot

qqs<-ggplot(dfccomp, aes(x=Year, y=sd,colour=Ratio))+geom_point()+
    facet_grid(Ratio~.)+
    theme(axis.text.x  = element_text(angle=-90, hjust=0.5, size=11,colour="black"))

这个情节适用于geom_point(),但现在适用于geom_line()。如果我使用geom_point(),那么多年来(从 1867 年到 2010 年)我的 x 轴都会变得非常混乱:

如果我使用 geom_line(),它不起作用,我会得到:

那么,我想知道如何只选择某些特定年份出现在 x 轴上?

2)我不明白的另一个奇怪的事情是如果我将上面的df$Year转换为数字,

df$Year=as.numeric(as.character(df$Year))

情节是:

现在,x 轴上只有 3 年。哪个更好,但仍然不是我想要的......

为什么geom_point()geom_line() 都有效?

更新: 在下面的答案中,我读到“年份是一个因素,因此 ggplot() 将相应地解释它并产生一个点图。geom_line() 没有做任何事情的原因是这个 geom 对于提供的数据没有意义;因子性质向 ggplot() 表明 x 轴是不连续的,并且在该轴上的点之间没有可以绘制的内容,因此没有线。”。

但我有一个不同的情节,其中geom_line() 与一个因素一起工作。为什么会这样?

qq<-ggplot(df, aes(x=Year, y=Mean,colour=Ratio)) + 
    geom_errorbar(aes(ymin=Mean-sd, ymax=Mean+sd), colour="black", width=.1, position=position_dodge(.1)) +
    geom_line(position=position_dodge(.1)) +
    geom_point(position=position_dodge(.1), size=3, shape=21, fill="white") + # 21 is filled circle
    xlab("Year") +
    ylab("Mean (%)")+ggtitle("Ratios")+facet_grid(Ratio~.)+theme(axis.text.x  = element_text(angle=-90, hjust=0.5, size=11,colour="black"))

图片:

【问题讨论】:

  • 您能否更新您的问题,以便我们可以“危害数据”或至少一个数字?不过,我怀疑您需要在您的 aes 调用中引入 group 变量。
  • 当然:) 我觉得很奇怪为什么 geom_line() 和 geom_point() 在 Year 是数字时都有效。但我最想知道如何调整 x 轴比例,所以比例不会像前两张图片那样混乱。最好的问候!

标签: r


【解决方案1】:

如果您使用Year 作为因子,ggplot 将为每个因子水平打印一个标签。您可以在前两个图中看到这一点。

如果您使用Year 作为数值变量,ggplot 将自动选择 x 轴标签值的子集。在您的第三个情节中,两次休息之间的距离是 100。

您可以使用scale_x_continuous 和参数breaks 手动指定x 轴上的断点位置。在下面的示例中,中断之间的距离为 20。使用代码来查找所需的绘图。

ggplot(df, aes(x=as.numeric(as.character(Year)), y=sd, colour=Ratio)) +
geom_point() +
facet_grid(Ratio~.) +
theme(axis.text.x  = element_text(angle=-90, hjust=0.5, size=11,colour="black")) +
scale_x_continuous(breaks = as.numeric(levels(df$Year))[c(TRUE, rep(FALSE, 19))])

【讨论】:

  • 谢谢斯文!实际上确实查找了 scale_x_continuous ,但可以设法正确获取它:) 再次感谢您的出色回答!
【解决方案2】:

Year 是一个因素,因此ggplot() 将相应地解释它并产生一个点图。 geom_line() 没有做任何事情的原因是这个 geom 对提供的数据没有意义;因子性质向ggplot() 表明,x 轴不是连续的,并且在该轴上的点之间没有可绘制的内容,因此没有线。

在将Year 转换为数字变量后,使用geom_line() 得到的数字清楚地表明了这种情况。现在ggplot(),按照它的语法,为连续的x轴数据生成一个折线图。

所以现在您的问题归结为控制 x 轴上的比例(比例是 ggplot() 所说的轴)。我看到两个选项;

  1. 使用scale_x_continous() 提供您自己的秤,如记录的here
  2. 将您的Year 数值数据转换为Date 对象,并让ggplot() 处理比例或通过scale_x_date() 对其进行自定义,如文档和说明的here

要转换为 Date 对象,您可以执行以下操作:

dfccomp <- transform(dfccomp,
                     Year = as.Date(paste(Year, "01", "01", sep = "-")))

将两个"01"s 更改为您想要的任何月份(第一个"01")或月份中的某天,但无论您选择什么,它实际上都是任意的,不是必需的;数据点将相隔 1 年。

然后您可以使用scale_x_date() 中的minor_breaks 参数来控制显示次要刻度的数量或位置,再加上breaks 参数来设置显示的年份。我建议你不要展示所有年份,否则结果会一团糟。你也不需要每年作为一个小休息,因为网格线只会淹没情节。

【讨论】:

  • 你快了几秒钟。
  • 谢谢加文!答案也很好!但是请参阅我对问题的更新,即使 Year 是一个因素, geom_line() 也有效......
  • @user1665355 无法判断那里发生了什么,图太小了,看不出来。我想是因为你躲避了少量,这是允许画一条线。您不需要像这样的技巧来绕过数据的格式化方式。您应该将数据格式化为正确的类型,以便 ggplot 生成正确的图形。您展示的新图与所有背景网格线有点乱。
  • 当然,我只是想了解它为什么起作用:) 但是非常感谢您的出色回答! R 有一条陡峭的学习曲线,感谢你们,对于我们其他用户来说,它变得不那么陡峭了:)
  • 没有您的数据我无法检查,但它真的有效吗?如果您在geom_line() 呼叫之后停止并且不添加任何其他层,您会得到一条线吗?如果没有您的数据,我自己无法运行此程序,您的图显示了 添加额外图层后的结果。如果它确实显示了一些东西,那么它是允许绘制一些线的躲避,但我怀疑它是正确的。