【问题标题】:How to shift limit scales in a ggplot with two y axis如何在具有两个 y 轴的 ggplot 中移动极限刻度
【发布时间】:2020-05-22 23:01:33
【问题描述】:

我正在研究ggplot2 以重现双 y 轴图。我正在处理的基本数据框是s4(我将在最后一面包含dput 版本)。我的数据框由一个id 变量和两个连续变量x 和y 组成。我用于情节的代码是下一个:

library(dplyr)
library(ggplot2)
library(tidyr)
#Transform
DF_long <- s4 %>%pivot_longer(names_to = "y_new", values_to = "val", x:y)
#Plot
ggplot(DF_long, aes(x=id)) +
  geom_bar( aes(y = val, fill = y_new, group = y_new),
            stat="identity", position=position_dodge(),alpha=.6)  +
  scale_fill_manual(values = c("blue", "red")) +
  scale_y_continuous(sec.axis = sec_axis(~.*0.1))+
  theme(axis.text.x = element_text(size=7,color='black',face='bold',angle = 90),
        axis.text.y = element_text(size=7,color='black',face='bold'),
        plot.title = element_text(hjust = 0.5,size=14,face="bold"),
        axis.title=element_text(size=10,face="bold"),
        strip.text.x = element_text(size = 8, face = "bold"),
        legend.position = "top",legend.title = element_blank(),panel.grid = element_blank(),
        legend.text = element_text(face='bold'),
        axis.title.x = element_blank()) 

代码有效,但没有产生我想要的输出。我得到了这个情节:

我的问题是由于两个 y 轴的限制,我无法可视化 x 变量。我希望能够看到这两个变量。请你帮我调整我的代码中的情节。下一个是s4 的dput 版本:

s4 <- structure(list(id = c("s1", "s2", "s3", "s4", "s5", "s6", "s7", 
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", "s16", 
"s17", "s18", "s19", "s20", "s21", "s22", "s23", "s24"), x = c(405L, 
409L, 257L, 306L, 509L, 103L, 100L, 118L, 41L, 231L, 93L, 255L, 
49L, 132L, 305L, 145L, 57L, 124L, 73L, 46L, 115L, 108L, 45L, 
26L), y = c(48148371.54, 35373940.7, 5256435.59, 5155308.9, 4155030.89, 
3792519.09, 2468987.02, 2264228.41, 2016421.67, 2001806.46, 1971658.78, 
1531488.5, 1358481.17, 1331466.48, 1072746.35, 992129.81, 954277.63, 
846098.66, 810819.33, 635270.45, 383283.61, 345273.12, 290598.09, 
265288.75)), row.names = c(NA, -24L), class = c("tbl_df", "tbl", 
"data.frame"))

非常感谢您的帮助。

【问题讨论】:

  • 第二个y轴的值是指什么?用两个 y 轴绘图通常不被认为是一件好事:stackoverflow.com/questions/3099219/…
  • @Peter 感谢您的帮助。 x 是项目数量,y 是美元金额。这就是为什么我需要两个轴。
  • @Peter 哦,谢谢,这是我需要的。只是我想知道是否有任何方法可以确定比例因子?我对此有麻烦。我会接受你的回答。
  • @Peter 是的,这将非常有用。
  • 答案已更新

标签: r ggplot2


【解决方案1】:

您的 cmets 使问题更清晰;我已经相应地更新了答案。

通常认为不适合使用双标度 y 轴,尤其是与条形图一起使用,应不鼓励使用。 (转述自下面提到的 Few 文章)

有关该问题的讨论,请参见:How can I plot with 2 different y-axes?、ggplot with 2 y axes on each side and different scales 和 Stephen Few 的链接文章:http://www.perceptualedge.com/articles/visual_business_intelligence/dual-scaled_axes.pdf

library(ggplot2)
library(dplyr)
library(tidyr)

确定一个比例因子以将您的 y2 数据“映射”到 y1 数据

可能有一种程序化的方法可以做到这一点,但我已经通过查看两个变量的范围和一些试验和错误来了解图表上的工作原理。检查两个 y 变量之间的比率。您的y2_factor 可能介于这些比率之间。但是你需要玩弄图表中看起来最好的东西。我选择了 90,000,它更接近于变量最大值的比率。


range(s4$y)/range(s4$x)
[1] 10203.41 94594.05

y2_factor <- 90000



转换你原来的 x 值;

我通过创建一个单独的变量来做到这一点,因此用于绘图的值和真实值之间没有混淆

DF_long <- 
  s4  %>% 
  mutate(x1 = x * y2_factor) %>% 
  pivot_longer(names_to = "y_new", values_to = "val", c(x1, y))

剧情

ggplot(DF_long, aes(x=id)) +
  geom_bar(aes(y = val, fill = y_new, group = y_new),
            stat="identity", position=position_dodge(),alpha=.6)  +
  scale_fill_manual(values = c("blue", "red"), labels = c("Number of items", "Dollars")) +
  # To get meaningful lables you  need invert the transformation process on the secondary axis by dividing values by the transforming factor
  # You can adjust the breaks and axis title to suit... 
  scale_y_continuous(sec.axis = sec_axis(~. / y2_factor, breaks = seq(0, 600, by = 50), name = "Number of items" ))+
  theme(axis.text.x = element_text(size=7,color='black',face='bold',angle = 90),
        axis.text.y = element_text(size=7,color='black',face='bold'),
        plot.title = element_text(hjust = 0.5,size=14,face="bold"),
        axis.title=element_text(size=10,face="bold"),
        strip.text.x = element_text(size = 8, face = "bold"),
        legend.position = "top",legend.title = element_blank(),panel.grid = element_blank(),
        legend.text = element_text(face='bold'),
        axis.title.x = element_blank()) 

你会得到这个:




<sup>Created on 2020-05-23 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>



【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    相关资源
    最近更新 更多