使用ggplot2仅将一个轴转换为log10比例

dar*_*zig 38 r ggplot2 boxplot scaletransform

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

让我们看一个钻石数据的简单例子:

m <- ggplot(diamonds, aes(y = price, x = color))
Run Code Online (Sandbox Code Playgroud)

替代文字

问题在这里并不严重,但我希望你能想象为什么我希望以log10的比例看到这些值.我们来试试吧:

m + geom_boxplot() + coord_trans(y = "log10")
Run Code Online (Sandbox Code Playgroud)

替代文字

正如您所看到的那样,y轴是log10缩放并且看起来很好但是x轴存在问题,这使得绘图非常奇怪.

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

m + geom_boxplot() + scale_y_log10() 
Run Code Online (Sandbox Code Playgroud)

替代文字

我的问题:有没有人知道在y轴上用log10刻度绘制boxplot的解决方案,标签可以用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
Run Code Online (Sandbox Code Playgroud)

使用不变的y轴标签:

替代文字

42-*_*42- 27

最简单的方法是给formatter参数指定日志函数的名称:

m + geom_boxplot() + scale_y_continuous(trans='log10')
Run Code Online (Sandbox Code Playgroud)

编辑:或者,如果你不喜欢它,那么其中任何一个似乎给出相同的结果:

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()
Run Code Online (Sandbox Code Playgroud)

EDIT2&3:进一步的实验(在丢弃试图成功地在记录值前面加上"$"符号的那个之后):

fmtExpLg10 <- function(x) paste(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)
Run Code Online (Sandbox Code Playgroud)

替代文字

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

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

  • `scale_y_continuous(formatter ='log10')`现在是`scale_y_continuous(trans ='log10')`(ggplot2 v2.2.1) (9认同)
  • 我怀疑你正在尝试做一些像'ggplot(钻石,aes(颜色,log10(价格)))+ geom_boxplot()+ scale_y_continuous(formatter = function(x)format(10 ^ x))` - 你需要转换数据并对标签进行反向转换. (2认同)

Sus*_*ser 16

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

breaks = 10**(1:10)
scale_y_log10(breaks = breaks, labels = comma(breaks))
Run Code Online (Sandbox Code Playgroud)

如你想要中间级别(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))
Run Code Online (Sandbox Code Playgroud)

执行后::

在此输入图像描述

  • 感谢您将注意力指向这个替代解决方案,该解决方案将完成指定简单的`dollar`格式化程序或编写自定义格式化程序:`+ scale_y_log10(breaks = breaks,labels = dollar(breaks))` (2认同)

Tun*_*ung 8

使用scale_y_log10with 的另一种解决方案trans_breakstrans_formatannotation_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())
Run Code Online (Sandbox Code Playgroud)

  • 非常优雅的输出 (2认同)
  • 2020 年,这是第一个复制粘贴有效的答案。(是的,我都试过了。) 谢谢! (2认同)