首页 > 解决方案 > 如何在 R 中以 2 y 轴平滑我的线?

问题描述

我有一个带有 2 y 轴的图表,我在上面绘制了一个条形图和一个折线图。折线图每个月都有 1 个值,但我想平滑折线图,同时仍保持 2 y 轴。当我使用该函数loess时,它不适用于 2 y 轴的图形,并且spline给我的值与我的原始值完全不同。

这里有一些类似于我所拥有的示例数据:

month_new = month.abb
Temp = sample(25, 12)
mapoc_temp = cbind(month_new, Temp)

num_unique_tags = sample(25, 12)
month = month.abb
bargraph_dets_temp = cbind(month, num_unique_tags)

我用下面的代码来绘制这个数据

ggplot(bargraph_dets_temp, 
       aes(x = month, y = num_unique_tags)) +
  #for my detection data
  geom_col(position = position_dodge()) +
  #For my temperature data
  geom_line(inherit.aes = FALSE, data = mapoc_temp,
            aes(x = month_new, y = as.numeric(Temp) + 2, group = 2),
            color = "forestgreen", size = 2) +
  #Make sure the 2 graphs share the same x axis
  scale_x_discrete(limits = c("Jan","Feb","Mar","Apr","May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")) +
  #putting 2 y scales on one graph
  scale_y_continuous(limits = c(0,30), name = "Total Unique Detections", 
                     sec.axis = sec_axis(~ . -2 , name = "Temperature (°C)"))


它给我的图片看起来像这样

在此处输入图像描述

我不关心折线图的详细程度我只想显示增加和减少值的一般模式,有人知道如何使线条看起来更平滑吗?

标签: rggplot2graph

解决方案


最简单的方法是使用样条插值您拥有的数据。您应该意识到的第一件事是monthmonth_new被视为具有 值1:12的数字ggplot。但是您使用自定义限制绘制离散 x 轴的方式会导致麻烦。相反,为了更好地控制此映射,您应该将离散 x 值编码为在其水平上具有给定顺序的因子:

plot_data <- data.frame(month = factor(month.abb, levels = month.abb), 
                        temp = sample(25, 12),
                        num_unique_tags = sample(25, 12))

您可以绘制数据

library(ggplot2)

ggplot(plot_data, aes(x = month, y = num_unique_tags)) + 
  geom_col() + 
  geom_line(aes(y = temp, group = 2), color = "forestgreen", size = 2) +
  scale_y_continuous(limits = c(0, 30), name = "Total Unique Detections", 
                     sec.axis = sec_axis(~ . -2 , name = "Temperature (°C)"))

要进行插值,您只需使用插值数据创建一个新数据集并绘制:

plot_data_interp <- as.data.frame(spline(x = 1:12, y = plot_data$temp, xout = seq(1, 12, length = 100)),
                               col.names = c('month', 'temp'))

ggplot(plot_data, aes(x = month, y = num_unique_tags)) + 
  geom_col() + 
  geom_line(aes(y = temp, group = 2), data = plot_data_interp, color = "forestgreen", size = 2) +
  scale_y_continuous(limits = c(0, 30), name = "Total Unique Detections", 
                     sec.axis = sec_axis(~ . -2 , name = "Temperature (°C)"))

如果你想平滑数据,你可以这样做(例如使用平滑样条):

plot_data_smooth <- as.data.frame(predict(smooth.spline(x = 1:12, y = plot_data$temp, spar = 0.5), x = seq(1, 12, length = 100)),
                                  col.names = c('month', 'temp'))

ggplot(plot_data, aes(x = month, y = num_unique_tags)) + 
  geom_col() + 
  geom_line(aes(y = temp, group = 2), data = plot_data_smooth, color = "forestgreen", size = 2) +
  scale_y_continuous(limits = c(0, 30), name = "Total Unique Detections", 
                     sec.axis = sec_axis(~ . -2 , name = "Temperature (°C)"))

结果如下:


推荐阅读