56

我有以下问题:我想在箱线图上可视化离散变量和连续变量,其中后者具有一些极高的值。这使得箱线图毫无意义(图表的点甚至“主体”都太小了),这就是为什么我想以 log10 的比例显示它。我知道我可以从可视化中省略极端值,但我不打算这样做。

让我们看一个带有钻石数据的简单示例:

m <- ggplot(diamonds, aes(y = price, x = color))

替代文字

这里的问题并不严重,但我希望你能想象为什么我希望看到 log10 比例的值。让我们尝试一下:

m + geom_boxplot() + coord_trans(y = "log10")

替代文字

如您所见,y 轴是 log10 缩放的,看起来不错,但 x 轴有问题,这使得绘图非常奇怪。

问题不会发生scale_log,但这不是我的选择,因为我不能以这种方式使用自定义格式化程序。例如:

m + geom_boxplot() + scale_y_log10() 

替代文字

我的问题:有谁知道在 y 轴上绘制带有 log10 比例的箱线图的解决方案,哪些标签可以用这个线程formatter中的函数自由格式化?


根据答案和评论编辑问题以帮助回答者:

我真正追求的是:一个没有科学标签的 log10 转换轴 (y)。我想将其标记为美元(formatter=dollar)或任何自定义格式。

如果我尝试@hadley 的建议,我会收到以下警告:

> m + geom_boxplot() + scale_y_log10(formatter=dollar)
Warning messages:
1: In max(x) : no non-missing arguments to max; returning -Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
3: In max(x) : no non-missing arguments to max; returning -Inf

使用不变的 y 轴标签:

替代文字

4

4 回答 4

40

最简单的方法是只给出所需日志函数的名称scale_x_continuous或名称的“trans”(以前的“formatter”)参数:scale_y_continuous

library(ggplot2)  # which formerly required pkg:plyr
m + geom_boxplot() + scale_y_continuous(trans='log10')

编辑:或者如果你不喜欢这样,那么这些中的任何一个似乎都会给出不同但有用的结果:

m <- ggplot(diamonds, aes(y = price, x = color), log="y")
m + geom_boxplot() 
m <- ggplot(diamonds, aes(y = price, x = color), log10="y")
m + geom_boxplot()

EDIT2 & 3: 进一步的实验(在丢弃尝试成功将“$”符号放在记录值前面的实验之后):

# Need a function that accepts an x argument
# wrap desired formatting around numeric result
fmtExpLg10 <- function(x) paste(plyr::round_any(10^x/1000, 0.01) , "K $", sep="")

ggplot(diamonds, aes(color, log10(price))) + 
  geom_boxplot() + 
  scale_y_continuous("Price, log10-scaling", trans = fmtExpLg10)

替代文字

注意在 2017 年中期添加了关于包语法更改的评论:

scale_y_continuous(formatter = 'log10') 现在是 scale_y_continuous(trans = 'log10') (ggplot2 v2.2.1)

于 2011-01-15T14:35:47.117 回答
19

我有一个类似的问题,这个规模对我来说就像一个魅力:

breaks = 10**(1:10)
scale_y_log10(breaks = breaks, labels = comma(breaks))

由于您也想要中间级别(10 ^ 3.5),因此您需要调整格式:

breaks = 10**(1:10 * 0.5)
m <- ggplot(diamonds, aes(y = price, x = color)) + geom_boxplot()
m + scale_y_log10(breaks = breaks, labels = comma(breaks, digits = 1))

执行后::

在此处输入图像描述

于 2011-02-09T10:30:21.393 回答
9

scale_y_log10使用withtrans_breakstrans_format的另一种解决方案annotation_logticks()

library(ggplot2)

m <- ggplot(diamonds, aes(y = price, x = color))

m + geom_boxplot() +
  scale_y_log10(
    breaks = scales::trans_breaks("log10", function(x) 10^x),
    labels = scales::trans_format("log10", scales::math_format(10^.x))
  ) +
  theme_bw() +
  annotation_logticks(sides = 'lr') +
  theme(panel.grid.minor = element_blank())

于 2018-08-08T16:42:06.030 回答
1

我想我最终通过在可视化之前对数据进行一些手动转换得到了它:

d <- diamonds
# computing logarithm of prices
d$price <- log10(d$price)

并制定一个格式化程序,以便稍后计算“返回”对数数据:

formatBack <- function(x) 10^x 
# or with special formatter (here: "dollar")
formatBack <- function(x) paste(round(10^x, 2), "$", sep=' ') 

并使用给定的格式化程序绘制绘图:

m <- ggplot(d, aes(y = price, x = color))
m + geom_boxplot() + scale_y_continuous(formatter='formatBack')

替代文字

很抱歉社区打扰你一个我以前可以解决的问题!有趣的是:一个月前我一直在努力使这个情节成功,但没有成功。在这里询问后,我明白了。

无论如何,感谢@DWin 的激励!

于 2011-01-15T17:47:05.560 回答