使用ggplot2(动态非手动)的日志正常比例的漂亮刻度

Mat*_*s_H 40 plot r ggplot2

我正在尝试使用ggplot2创建一个日志正常y比例的性能图表.不幸的是,我不能像基本情节函数那样产生好的滴答声.

这是我的例子:

library(ggplot2)
library(scales)

# fix RNG
set.seed(seed = 1)

# simulate returns
y=rnorm(999, 0.02, 0.2)

# M$Y are the cummulative returns (like an index)
M = data.frame(X = 1:1000, Y=100)

for (i in 2:1000)
  M[i, "Y"] = M[i-1, "Y"] * (1 + y[i-1])

ggplot(M, aes(x = X, y = Y)) + geom_line() + scale_y_continuous(trans = log_trans())
Run Code Online (Sandbox Code Playgroud)

产生难看的蜱:

在此输入图像描述

我也尝试过:

在此输入图像描述

ggplot(M, aes(x = X, y = Y)) + geom_line() + 
  scale_y_continuous(trans = log_trans(), breaks = pretty_breaks())
Run Code Online (Sandbox Code Playgroud)

如何获得与默认绘图函数相同的中断/刻度:

plot(M, type = "l", log = "y")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

结果应该看起来像这样,但不是硬打字,而是动态的.我尝试了类似axisTicks()但不成功的功能:

ggplot(M, aes(x = X,y = Y)) + geom_line() + 
  scale_y_continuous(trans = log_trans(), breaks = c(1, 10, 100, 10000))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

谢谢!

编辑:插入图片

Hea*_*ner 35

可以使用自定义中断函数重现基本图形行为:

base_breaks <- function(n = 10){
    function(x) {
        axisTicks(log10(range(x, na.rm = TRUE)), log = TRUE, n = n)
    }
}
Run Code Online (Sandbox Code Playgroud)

将此应用于示例数据会产生与使用相同的结果trans_breaks('log10', function(x) 10^x):

ggplot(M, aes(x = X, y = Y)) + geom_line() +
    scale_y_continuous(trans = log_trans(), breaks = base_breaks()) + 
    theme(panel.grid.minor = element_blank())
Run Code Online (Sandbox Code Playgroud)

打破十的权力

但是,我们可以对数据子集使用相同的函数,y值介于50和600之间:

M2 <- subset(M, Y > 50 & Y < 600)
ggplot(M2, aes(x = X, y = Y)) + geom_line() +
    scale_y_continuous(trans = log_trans(), breaks = base_breaks()) + 
    theme(panel.grid.minor = element_blank())
Run Code Online (Sandbox Code Playgroud)

由于10的权力不再适合这里,base_breaks产生替代的漂亮休息:

很好的休息

请注意,我已经关闭了较小的网格线:在某些情况下,在y轴上的主要网格线之间有网格线是有意义的,但并非总是如此.

编辑

假设我们修改M以使最小值为0.1:

M <- M - min(M) + 0.1
Run Code Online (Sandbox Code Playgroud)

base_breaks()函数仍然选择漂亮的中断,但标签是科学记数法,可能不会被视为"漂亮":

ggplot(M, aes(x = X, y = Y)) + geom_line() +
    scale_y_continuous(trans = log_trans(), breaks = base_breaks()) + 
    theme(panel.grid.minor = element_blank())
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我们可以通过将文本格式化函数传递给labels参数来控制文本格式scale_y_continuous.在这种情况下prettyNum,基本包可以很好地完成工作:

ggplot(M, aes(x = X, y = Y)) + geom_line() +
scale_y_continuous(trans = log_trans(), breaks = base_breaks(),
                   labels = prettyNum) + 
theme(panel.grid.minor = element_blank())
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 不错的方法,谢谢分享 (2认同)

csg*_*pie 21

当我在日志规模上构建图形时,我发现以下工作非常好:

library(ggplot2)
library(scales)

g = ggplot(M,aes(x=X,y=Y)) + geom_line()
g +  scale_y_continuous(trans = 'log10',
                        breaks = trans_breaks('log10', function(x) 10^x),
                        labels = trans_format('log10', math_format(10^.x)))
Run Code Online (Sandbox Code Playgroud)

有几点不同:

  1. 轴标签显示为10的幂 - 我喜欢
  2. 次要网格线位于主要网格线的中间(将此图与Andrie的答案中的网格线进行比较).
  3. x轴更好.出于某种原因,在Andrie的情节中,x轴范围是不同的.

在此输入图像描述

  • 只是为了完成这个答案:函数`trans_breaks`和`trans_format`是`scales`库的一部分. (4认同)

And*_*rie 16

基本图形函数axTicks()返回当前图的轴中断.因此,您可以使用它来返回与基本图形相同的中断.唯一的缺点是你必须首先绘制基本图形图.

library(ggplot2)
library(scales)


plot(M, type="l",log="y")
breaks <- axTicks(side=2)
ggplot(M,aes(x=X,y=Y)) + geom_line() +
  scale_y_continuous(breaks=breaks) +
  coord_trans(y="log")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Joe*_*Joe 8

这个问题终于随着scales 1.0.0和新函数的发布而得到解决log_breaks(),它返回 base 的整数次幂的整数倍。

library(ggplot2)
ggplot(M, aes(x = X,y = Y)) + 
  geom_line() + 
  scale_y_log10(breaks = log_breaks())
Run Code Online (Sandbox Code Playgroud)