R中的双Y轴图

时间:2019-12-17 17:16:58

标签: r ggplot2 plot

我想用双Y轴构建图。

在图像中,您可以看到我的数据框和图。它是在Excel中完成的,我需要在R中做同样的事情。我尝试使用latticeExtra库,但是它不显示任何行和框

library(latticeExtra)
obj1 <- xyplot(Q_TY_PAPER ~ PU, df, type = "h")
obj2 <- xyplot(COM_USD ~ PU, df, type = "l")
doubleYScale(obj1, obj2, text = c("obj1", "obj2"))`

你能帮我吗?

这是我想要获取的数据集和图的捕获: enter image description here

1 个答案:

答案 0 :(得分:1)

您需要将数据框一分为二,一个将用于条形图并需要重塑形状,第二个将用于需要缩放的线。

基本上,将在与条形图相同的y轴上绘制该线,但是,我们将添加一个辅助y轴,该第二y轴上的标记对应于该线的“实际”值。

因此,首先,我们需要将值图重新缩放为一条线。就像我们在您的示例中看到的那样,条形图中的值8与该行的值500匹配,我们可以通过应用8/500的比例来重新缩放:

df_line = df[,c("PU","COM_USD")]
df_line$COM_USD_2 = df_line$COM_USD * 8/500

> df_line
       PU COM_USD COM_USD_2
1 Client1     464     7.424
2 Client2     237     3.792
3 Client3     179     2.864
4 Client4      87     1.392
5 Client5      42     0.672
6 Client6      27     0.432
7 Client7      10     0.160

对于条形图,我们需要将数据转换为更长的格式,以适应ggplot2的语法。为此,我们可以使用pivot_longer包中的tidyr(已加载tidyverse):

library(tidyverse)
df_bar <- df %>% select(-COM_USD) %>% pivot_longer(., - PU, names_to = "Variable", values_to = "Value")

# A tibble: 21 x 3
   PU      Variable    Value
   <fct>   <chr>       <dbl>
 1 Client1 Q_TY_PAPER    7.1
 2 Client1 Q_TY_ONLINE   7.1
 3 Client1 CURR          6  
 4 Client2 Q_TY_PAPER    3.8
 5 Client2 Q_TY_ONLINE   3.8
 6 Client2 CURR          3.9
 7 Client3 Q_TY_PAPER    4.4
 8 Client3 Q_TY_ONLINE   4.4
 9 Client3 CURR          2.3
10 Client4 Q_TY_PAPER    2.6
# … with 11 more rows

现在,您可以通过执行以下操作来绘制它们:

library(tidyverse)

ggplot(df_bar, aes(x = PU, y = Value))+ 
  geom_bar(aes(fill = Variable), stat = "identity", position = position_dodge(), alpha = 0.8)+
  geom_line(data = df_line, aes(x = PU, y = COM_USD_2, group = 1), size = 2, color = "blue")+
  scale_y_continuous(name = "Quantity", limits = c(0,8), sec.axis = sec_axis(~(500/8)*., name = "USD"))+
  theme(legend.title = element_blank(),
        axis.title.x = element_blank())

如您所见,在scale_y_continuous中,我们设置了第二个轴,该轴的刻度值乘以反向比率(500/8)。这样,它将匹配绘制的线的值。

最后,您得到以下绘图:

enter image description here

数据

PU = paste0("Client",1:7)
COM_USD = c(464,237,179,87,42,27,10)
Q_TY_PAPER = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
Q_TY_ONLINE = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
CURR = c(6.0,3.9,2.3,0.2,0.2,0.1,0)

df = data.frame(PU,COM_USD, Q_TY_PAPER, Q_TY_ONLINE, CURR)

编辑:将长名称作为x轴标签处理

如果客户端的真实数据名称太长,则可以使用此解决方案(Two lines of X axis labels in ggplot)在两行中写入它们。

因此,首先修改PU变量:

PU = c("Jon Jon", "Bob Bob", "Andrew Andrew", "Henry Henry", "Alexander Alexander","Donald Donald", "Jack Jack")
COM_USD = c(464,237,179,87,42,27,10)
Q_TY_PAPER = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
Q_TY_ONLINE = c(7.1,3.8,4.4,2.6,1.2,1.1,0.5)
CURR = c(6.0,3.9,2.3,0.2,0.2,0.1,0)

df = data.frame(PU,COM_USD, Q_TY_PAPER, Q_TY_ONLINE, CURR)

然后,我们应用与上述相同的代码:

df_line = df[,c("PU","COM_USD")]
df_line$COM_USD_2 = df_line$COM_USD * 8/500

library(tidyverse)
df_bar <- df %>% select(-COM_USD) %>% pivot_longer(., - PU, names_to = "Variable", values_to = "Value")

但是对于绘图,您可以使用scale_x_discrete并通过添加labels来指定\n来表示R以在多行上写x标签:

ggplot(df_bar, aes(x = PU, y = Value))+ 
  geom_bar(aes(fill = Variable), stat = "identity", position = position_dodge(), alpha = 0.8)+
  geom_line(data = df_line, aes(x = PU, y = COM_USD_2, group = 1), size = 2, color = "blue")+
  scale_y_continuous(name = "Quantity", limits = c(0,8), sec.axis = sec_axis(~(500/8)*., name = "USD"))+
  theme(legend.title = element_blank(),
        axis.title.x = element_blank())+
  scale_x_discrete(labels = gsub(" ","\n",PU), breaks = PU)

您会得到: enter image description here

相关问题