简体   繁体   English

R 中的辅助轴未注册

[英]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:这有两个错误:

  1. The primary (left) y-axis now scales from 0 to 100, scrunching the primary y values to the bottom of the plot;主(左)y 轴现在从 0 缩放到 100,将主y值压缩到图的底部; and
  2. Related, the secondary (right) y-axis scales from 0 to 1000?!?相关的,次要(右)y 轴从 0 到 1000 缩放?!? This is because the only thing that the secondary axis "knows" is the values that go into the primary axis ... and the primary axis is scaling to fit all of the y* 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM