使用 ggplot2(动态非手动)对数正常刻度的漂亮刻度 [英] Pretty ticks for log normal scale using ggplot2 (dynamic not manual)

查看:32
本文介绍了使用 ggplot2(动态非手动)对数正常刻度的漂亮刻度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 ggplot2 创建一个具有对数正态 y 刻度的性能图表.不幸的是,对于基本绘图函数,我无法产生很好的刻度.

I am trying to use ggplot2 to create a performance chart with a log normal y scale. Unfortunately I'm not able to produce nice ticks as for the base plot function.

这是我的例子:

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())

产生丑陋的滴答声:

我也试过:

ggplot(M, aes(x = X, y = Y)) + geom_line() + 
  scale_y_continuous(trans = log_trans(), breaks = pretty_breaks())

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

How can I get the same breaks/ticks as in the default plot function:

plot(M, type = "l", log = "y")

结果应该是这样的,但不是硬输入中断而是动态的.我尝试过像 axisTicks() 这样的函数,但没有成功:

The result should look like this but not with hard-typing the breaks but dynamic. I tried functions like axisTicks() but was not successful:

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

谢谢!

插入图片

推荐答案

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

The base graphics behaviour can be reproduced using a custom breaks function:

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

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

Applying this to the example data gives the same result as using 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())

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

However we can use the same function on a subset of the data, with y values between 50 and 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())

由于 10 的幂在这里不再合适,base_breaks 产生替代的漂亮中断:

As powers of ten are no longer suitable here, base_breaks produces alternative pretty breaks:

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

Note that I have turned off minor grid lines: in some cases it will make sense to have grid lines halfway between the major gridlines on the y-axis, but not always.

编辑

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

Suppose we modify M so that the minimum value is 0.1:

M <- M - min(M) + 0.1

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

The base_breaks() function still selects pretty breaks, but the labels are in scientific notation, which may not be seen as "pretty":

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

我们可以通过向scale_y_continuouslabels 参数传递一个文本格式函数来控制文本格式.在这种情况下,基础包中的 prettyNum 可以很好地完成这项工作:

We can control the text formatting by passing a text formatting function to the labels argument of scale_y_continuous. In this case prettyNum from the base package does the job nicely:

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())

这篇关于使用 ggplot2(动态非手动)对数正常刻度的漂亮刻度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆