在ggplot中,是否有设置将“,”作为轴标签默认小数点的选项?

6

在制作图表时,ggplot2为需要额外工作才能实现相同结果的比例尺提供了很多明智的默认设置。

举个例子:

library("ggplot2")
ggplot(mtcars, aes(drat, mpg)) + geom_point()

请注意,这个图表小数点后只有一位数字。
然而,我住在荷兰,我们习惯使用逗号作为小数点。这可以在“scale_x_continuous”中轻松完成。
ggplot(mtcars, aes(drat, mpg)) + 
  geom_point() + 
  scale_x_continuous(labels = scales::label_number(big.mark = ".", decimal.mark = ","))

这个解决方案让我感到困扰的是,它也增加了数字的数量:每个标签末尾都有一个额外、不必要的 0。当然,这也可以在 scales::label_number() 中通过设置 accuracy = 0.1 来解决,但这需要迭代(绘制和重新绘制以设置更合理的数字位数)。
是否有一种选项可以修复 ggplot 使用的默认小数标记?我正在寻找一种解决方案,其中
ggplot(mtcars, aes(drat, mpg)) + 
  geom_point()

返回与原图相同的绘图

ggplot(mtcars, aes(drat, mpg)) + 
  geom_point() + 
  scale_x_continuous(labels = scales::label_number(
    big.mark = ".", 
    decimal.mark = ",",
    accuracy = 0.1
  ))
3个回答

4

不仅适用于 ggplot2,您还可以使用 options(OutDec = ",") 全局设置输出数字的小数点符号。

来自帮助页面:

OutDec:包含单个字符的字符字符串。优选要在输出转换中(即打印、绘图、格式和as.character中)用作小数点的字符,但不包括在解析之前使用的sprintf和formatC,也不包括在打印之前有时会使用的方式。

library(ggplot2)

options(OutDec= ",")

ggplot(mtcars, aes(drat, mpg)) + 
  geom_point()

enter image description here


谢谢Ritchie!我接受Ben的答案,因为它是一个ggplot2特定的解决方案,但这也非常有帮助。 - MartenMM
此外,似乎没有全局千位分隔符参数可以传递给 options() - TemplateRex

3
一个更通用的解决方案是编写一个与兼容的标签函数, 在底层调用, 然后创建一个具有荷兰标点约定的特殊版本。
library(ggplot2)
library(scales)

ggplot(mtcars, aes(drat, mpg)) + 
  geom_point()

# Use base::format as a {scales}-compatible labels function
label_format <- function(...) {
  function(x) do.call(format, c(list(x = x), list(...)))
}

# Specialized version for Dutch punctuation
label_format_NL <- function(...) {
  label_format(big.mark = ".", decimal.mark = ",", ...)
}

ggplot(mtcars, aes(drat, mpg)) + 
  geom_point() + 
  scale_x_continuous(labels = label_format_NL())

如果您不喜欢必须为每个轴指定标签,您可以通过重写ggplot2 :: continuous_scale来实现,例如:

continuous_scale <- function(...) {
  do.call(
    ggplot2::continuous_scale, 
    c(list(labels = label_format_NL()), list(...))
  )
}

ggplot(mtcars, aes(drat, mpg)) + 
  geom_point()

个人而言,我会使用显式的 scale_AESTHETIC_continous(labels = label_format_NL()),因为这样可以使你的更改局部化。覆盖 options()continuous_scale() 的行为等同于全局变量,不建议使用。


1
这段代码与我的答案非常相似,只不过你的 label_format 函数更漂亮一些。 - Ben Bolker

3

关键似乎在于format(来自基本 R)和scales::number使用不同的规则。我们可以恢复使用format...

myf <- function(x, ...) format(x, big.mark = ".", decimal.mark = ",", ...)
ggplot(mtcars, aes(drat, mpg)) +
  geom_point() +
  scale_x_continuous(labels = myf)

如果您希望将这些标签设置为全局默认值,我认为您可以这样做:
scale_x_continuous <- function(..., labels = myf) {
  do.call(ggplot2::scale_x_continuous, c(list(...), labels = labels))
}

有没有一种方法可以同时设置所有比例尺(scale_y_continuous()scale_fill_continuous()等)?我尝试了 continuous_scale <- function(...,labels = myf) do.call(ggplot2::continuous_scale, c(list(...), labels = labels)) ,但似乎不起作用。 - MartenMM
据我所知没有,但如果你只需要在一个会话中执行一次,那么问题不大...可以通过循环字符串并使用“assign”来实现,但是这样做有点麻烦... - Ben Bolker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接