我在R stat_function
中试图了解ggplot2
时遇到了严重问题。我从这个琐碎的例子开始:
ggplot(data.frame(x = c(1, 1e4)), aes(x)) + stat_function(fun = function(x) x)
按预期工作。不幸的是,当我为x轴和y轴添加对数刻度时:
ggplot(data.frame(x = 1:1e4), aes(x)) +
scale_x_log10() +
scale_y_log10() +
stat_function(fun = function(x) x)
我得到以下结果,这是一个非常讨厌的身份函数违规。
我缺少一些非常基本的东西吗?那么在对数尺度上绘制函数的正确和最简单的方法是什么?
修改
受到答案的启发,我继续尝试使用比例和aesthetics
参数。我更加困惑的是发现我使用下面的代码得到了我的预期:
ggplot(data.frame(x = 1:1e4, y = 1:1e4), aes(x, y)) +
scale_x_log10() +
scale_y_log10() +
stat_function(fun = function(x) x)
带有明显未使用的y值向量(stat_function
未使用)。轴转换是否取决于数据的可用性?
答案 0 :(得分:5)
当您使用scale_x_log10()
时,x
值会被日志转换,然后才会用y
计算stat_function()
值。然后将x
值反向转换为原始值以进行缩放。 y
值保留为从日志转换后的x
计算得出的值。您可以通过绘制没有scale_y_log10()
的值来检查这一点。在情节中有直线。
ggplot(data.frame(x=1:1e4), aes(x)) +
stat_function(fun = function(x) x) +
scale_x_log10()
如果您应用scale_y_log10()
,则会记录已经计算过的y
值,因此会绘制曲线。
答案 1 :(得分:5)
在ggplot2中,规则是尺度变换先于统计变换,而统计变换又在坐标变换之前。在此上下文中,函数(通过stat_function())是统计变换。
如果在ggplot2调用中使用scale_x / y _ *()函数,它将在计算函数之前首先应用缩放变换。
案例0:绘制x和y的原始比例。
ggplot(data.frame(x = 1:1e4, y = 1:1e4), aes(x, y)) +
stat_function(fun = function(x) x)
情况1a:由于存在scale_x / y_log10(),因此在计算函数之前对x和y进行对数转换。您可以从各自比例的值中看到这一点(与案例0比较)。
ggplot(data.frame(x = 1:1e4, y = 1:1e4), aes(x, y)) +
stat_function(fun = function(x) x) +
scale_x_log10() +
scale_y_log10()
情况1b:x在原始数据帧中进行对数变换。因此,函数实际上对log10(x)值进行操作,因此仍然是一条直线,但在x和y的log10范围内。
ggplot(data.frame(x = log10(seq(1e4)), y = seq(1e4)), aes(x, y)) +
stat_function(fun = function(x) x)
情况1c:与1b相同,但有一个例外:x尺度是原始单位,但y尺度是log10(x)单位,因为x上的尺度变换发生在统计变换f之前( y)= y被计算,其中y = log10(x)。
ggplot(data.frame(x = seq(1e4), y = seq(1e4)), aes(x, y)) +
stat_function(fun = function(x) x) +
scale_x_log10()
案例2:相反,在统计变换之后,坐标转换发生在;即,首先以原始单位计算函数,然后在x上进行坐标转换,这会使函数变形:
ggplot(data.frame(x = seq(1e4), y = seq(1e4)), aes(x, y)) +
stat_function(fun = function(x) x) +
coord_trans(xtrans = "log10")
...当然,除非你对x和y应用相同的转换:
ggplot(data.frame(x = seq(1e4), y = seq(1e4)), aes(x, y)) +
stat_function(fun = function(x) x) +
coord_trans(xtrans = "log10", ytrans = "log10")