r - 如何在 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)"))
它给我的图片看起来像这样
我不关心折线图的详细程度我只想显示增加和减少值的一般模式,有人知道如何使线条看起来更平滑吗?
解决方案
最简单的方法是使用样条插值您拥有的数据。您应该意识到的第一件事是month
和month_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)"))
结果如下:
推荐阅读
- javascript - 单击闪亮数据表中的按钮后如何滚动到底部
- c# - 您可以同时在两个单独的应用程序服务上运行网络作业(绕过单例锁)吗?
- android - 如何使用 Google 的应用内更新 API 指定哪些更新需要立即更新以及哪些更新是灵活的?
- java - 有没有办法通过用 Java 编码将一个 html 文件替换为另一个文件?
- proxy - 如何解决 Cloud Foundry 的代理错误?
- javascript - Lodash 将数组转换为对象
- sql - MD5 : Generate excel's files
- reactjs - Openlayers 修改交互
- c++ - 如何通过时间跟踪屏幕?
- java - 休眠延迟加载不适用于 java 11 中的 forEach()