[英]Secondary axis in R not registering
ggplot(df) +
geom_bar(aes(x=Date, y=DCMTotalCV, fill=CampaignName), stat='identity', position='stack') +
geom_line(aes(x=Date, y=DCMCPA, color=CampaignName, group=as.factor(CampaignName)), na.rm = FALSE,show.legend=NA)+
scale_y_continuous(sec.axis = sec_axis(~./1000, name = "DCMTotalCV"))+
theme_bw()+
labs(
x= "Date",
y= "CPA",
title = "Daily Performance"
)
Hey everyone - so I have 2 y-axes i want to plot.大家好 - 所以我有 2 个 y 轴我想绘制。 geom_line is registering fine on the main y-axis but geom_bar is not registering properly on the right.
geom_line 在主 y 轴上注册得很好,但 geom_bar 在右侧没有正确注册。 I tried scaling but it's still not registering or plotting on that second axis.
我尝试缩放,但它仍然没有在第二个轴上注册或绘图。 It looks like it's still appearing on the main y-axis so I'm wondering how to tell the plot to plot it on the second one?
看起来它仍然出现在主 y 轴上,所以我想知道如何告诉情节在第二个轴上绘制它? Sorry i'm kind of a newbie.
对不起,我是个新手。 Thanks!
谢谢!
data <- data.frame(
day = as.Date("2020-01-01"),
conversions = seq(1,6)^2,
cpa = 100000 / seq(1,6)^2
)
head(data)
str(data)
#plot
ggplot(data, aes(x=day)) +
geom_bar( aes(y=conversions), stat='identity') +
geom_line( aes(y=cpa)) +
scale_y_continuous(sec.axis = sec_axis(~./1000))
ggplot2::sec_axis
is intended only to put up the scale itself; ggplot2::sec_axis
仅用于放置比例尺本身; it does nothing to try to scale the values (that you are pairing with that axis).尝试缩放值(您与该轴配对)没有任何作用。 Why?
为什么? Primarily because it knows nothing about which
y
variable you are intending to pair with which y-axis.主要是因为它不知道您打算将哪个
y
变量与哪个 y 轴配对。 (Is there anywhere in sec_axis
to tell it that it should be looking at a particular variable? Nope.) (在
sec_axis
是否有任何地方告诉它应该查看特定变量?没有。)
As a demonstration, let's start with some random data and plot the line.作为演示,让我们从一些随机数据开始并绘制线条。
set.seed(42)
dat <- data.frame(x = rep(1:10), y1 = sample(10), y2 = sample(100, size = 10))
dat
# x y1 y2
# 1 1 1 47
# 2 2 5 24
# 3 3 10 71
# 4 4 8 89
# 5 5 2 37
# 6 6 4 20
# 7 7 6 26
# 8 8 9 3
# 9 9 7 41
# 10 10 3 97
ggplot(dat, aes(x, y1)) +
geom_line() +
scale_y_continuous(name = "Oops!")
Now you determine that you want to add the y2
variable in there, but because its values are on a completely different scale, you think to just add them (I'll use geom_text
here) and then set a second axis.现在您确定要在其中添加
y2
变量,但由于其值的比例完全不同,您认为只需添加它们(我将在此处使用geom_text
),然后设置第二个轴。
ggplot(dat, aes(x, y1)) +
geom_line() +
geom_text(aes(y = y2, label = y2)) +
scale_y_continuous(name = "Oops!", sec.axis = sec_axis(~ . * 10, name = "Quux!"))
Two things wrong with this:这有两个错误:
y
values to the bottom of the plot;y
值压缩到图的底部; andy*
variables it is told to plot.y*
变量。 That last point is important: this is giving y
values that scale from 0 to 100, so the axis will reflect that.最后一点很重要:这给出了从 0 到 100 的
y
值,因此轴将反映这一点。 You can do lims(y=c(0,10))
, but realize you'll be truncating y2
values ... that's not the right approach.你可以做
lims(y=c(0,10))
,但意识到你会截断y2
值......这不是正确的方法。
Instead, you need to scale the second values to be within the same range of values as the primary axis variable y1
.相反,您需要将第二个值缩放到与主轴变量
y1
相同的值范围内。 Though not required, I'll use scale::rescale
for this.虽然不是必需的,但我会为此使用
scale::rescale
。
dat$y2scaled <- scales::rescale(dat$y2, range(dat$y1))
dat
# x y1 y2 y2scaled
# 1 1 1 47 5.212766
# 2 2 5 24 3.010638
# 3 3 10 71 7.510638
# 4 4 8 89 9.234043
# 5 5 2 37 4.255319
# 6 6 4 20 2.627660
# 7 7 6 26 3.202128
# 8 8 9 3 1.000000
# 9 9 7 41 4.638298
# 10 10 3 97 10.000000
Notice how y2scaled
is now proportionately within y1
's range?请注意
y2scaled
现在如何按比例在y1
的范围内?
We'll use that to position each of the text objects (though we'll still show the y2
as the label here).我们将使用它来定位每个文本对象(尽管我们仍将在此处将
y2
显示为标签)。
ggplot(dat, aes(x, y1)) +
geom_line() +
geom_text(aes(y = y2scaled, label = y2)) +
scale_y_continuous(name = "Oops!", sec.axis = sec_axis(~ . * 10, name = "Quux!"))
Are we strictly required to make sure that the points pairing with the secondary axis perfectly fill the range of values of the primary axis?我们是否严格要求确保与辅助轴配对的点完全填充主轴的值范围? No. We could easily have thought to keep the text labels only on the bottom half of the plot, so we'd have to scale appropriately.
不。我们很容易想到只在图的下半部分保留文本标签,所以我们必须适当地缩放。
dat$y2scaled2 <- scales::rescale(dat$y2, range(dat$y1) / c(1, 2))
dat
# x y1 y2 y2scaled y2scaled2
# 1 1 1 47 5.212766 2.872340
# 2 2 5 24 3.010638 1.893617
# 3 3 10 71 7.510638 3.893617
# 4 4 8 89 9.234043 4.659574
# 5 5 2 37 4.255319 2.446809
# 6 6 4 20 2.627660 1.723404
# 7 7 6 26 3.202128 1.978723
# 8 8 9 3 1.000000 1.000000
# 9 9 7 41 4.638298 2.617021
# 10 10 3 97 10.000000 5.000000
ggplot(dat, aes(x, y1)) +
geom_line() +
geom_text(aes(y = y2scaled2, label = y2)) +
scale_y_continuous(name = "Oops!", sec.axis = sec_axis(~ . * 20, name = "Quux!"))
Notice that not only did I change how the y-axis values were scaled (now ranging from 0 to 5 in y2scaled2
), but I also had to change the transformation within sec_axis
to be *20
instead of *10
.请注意,我不仅更改了 y 轴值的缩放方式(现在
y2scaled2
范围从 0 到 5),而且我还必须将sec_axis
内的转换更改为*20
而不是*10
。
Sometimes getting these transformations correct can be confusing, and it is easy to mess them up.有时,正确地进行这些转换可能会令人困惑,而且很容易弄乱它们。 However ... realize that it took many years to even get this functionality into
ggplot2
, mostly due to the lead developer(s) belief that even when plotted well, they can be confusing to the viewer, and potentially provide misleading takeaways.然而……意识到甚至将这个功能引入
ggplot2
需要很多年,主要是由于主要开发人员认为即使绘制得很好,它们也会让观众感到困惑,并可能提供误导性的结论。 I find that they can be useful sometimes, and there are techniques one can use to encourage correct interpretation, but ... it's hard to get because it's easy to get wrong.我发现它们有时很有用,并且可以使用一些技巧来鼓励正确的解释,但是......很难获得,因为很容易出错。
As an example of one technique that helps distinguish which axis goes with which data, see this:作为一种有助于区分哪个轴与哪个数据对应的技术的示例,请参见:
ggplot(dat, aes(x, y1)) +
geom_line(color = "blue") +
geom_text(aes(y = y2scaled2, label = y2), color = "red") +
scale_y_continuous(name = "Oops!", sec.axis = sec_axis(~ . * 20, name = "Quux!")) +
theme(
axis.ticks.y.left = element_line(color = "blue"),
axis.text.y.left = element_text(color = "blue"),
axis.title.y.left = element_text(color = "blue"),
axis.ticks.y.right = element_line(color = "red"),
axis.text.y.right = element_text(color = "red"),
axis.title.y.right = element_text(color = "red")
)
(One might consider colors from viridis
for a more color-blind palette.) (人们可能会考虑
viridis
中的颜色以获得更色盲的调色板。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.