在ggplot中使用facet_wrap对时间序列进行X轴复制

时间:2018-06-26 01:51:43

标签: r ggplot2 time-series facet-wrap

希望您今天过得愉快!因此,我有一个大约二十年的大型数据集,我试图使用facet_wrap参数将其可视化。这是数据的简化版本,用于故障排除:

data <- data.frame(
Date = c("1993-06-09", "1993-08-16", "1993-09-13", "1993-10-11", "1993-11-08", "1994-03-06", "1994-05-20", "1994-07-12", "1994-12-06", "1994-09-07", "1995-04-04", "1995-01-07", "1995-02-06"),
Oxygen = c("15", "15.8", "15.3", "16", "16", "14.5", "14.9", "15.2", "15.7", "15", "12.6", "12.8", "13.5"),
Year = c("1993", "1993", "1993", "1993", "1993", "1994", "1994", "1994", "1994", "1994", "1995", "1995", "1995"),
Month = c("6", "8", "9", "10", "11", "3", "5", "7", "12", "9", "4", "1", "2"),
Day = c("9", "16", "13", "11", "8", "6", "20", "12", "6", "7", "4", "7", "6")
)

这是其余的代码:

data$Oxygen <- as.numeric(as.character(data$Oxygen))
data$Year <- as.numeric(as.character(data$Year))
data$Month <- as.numeric(as.character(data$Month))
data$Day <- as.numeric(as.character(data$Day))
data$Date <- as.Date(data$Date)
ggplot(data = data, aes(x=Date, y=Oxygen)) + geom_point() + geom_smooth(method = "loess", se=FALSE) + facet_wrap( ~ Year, ncol=2) + scale_x_date(date_breaks = "1 month", date_labels = "%B")  + theme(axis.text.x=element_text(angle = 90, hjust = 1)) +  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),panel.background = element_blank(), axis.line = element_line(colour = "black"))

代码创建以下图形:

img

我的问题是x轴。我应该如何更改它,以免彼此接连不断地连续几个月出现?我想要这样,以便所有年份都适合一年内的几个月,而又不会像每年不同一样创建更多个月。

这就是我剩下的几年的样子:

img

它绘制的是每年的x轴,而不仅仅是一年的几个月。

最后,我如何告诉ggplot我想查看每个月中的星期或天,以使并非所有的点都只是沿着x轴位于该月的固定点上。

谢谢您的时间!

2 个答案:

答案 0 :(得分:1)

要获得一致的月度休息时间,您可以设置日期的虚拟变量,所有日期都与同一年相同,并且按实际年份分面。这样,您在x轴上仍然有一个日期,可以访问scale_x_date,但可以按年份整齐地拆分数据。

出于简洁和偏好,我使用dplyr进行了清理,并创建了一个虚拟日期列,将年份更改为2018,然后使用lubridate::ymd转换为日期对象。

library(tidyverse)
library(lubridate)

data2 <- data %>%
  mutate_at(vars(-Date), function(x) as.numeric(as.character(x))) %>%
  mutate(Date = as.Date(Date)) %>%
  mutate(dummy_date = paste("2018", Month, Day) %>% ymd())


ggplot(data2, aes(x = dummy_date, y = Oxygen, group = Year)) +
  geom_point() +
  geom_smooth(method = loess, se = FALSE) +
  scale_x_date(date_breaks = "1 month", date_labels = "%B") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
  facet_wrap(~ Year, ncol = 2)

reprex package(v0.2.0)于2018-06-25创建。

答案 1 :(得分:0)

选项1 :(从注释中重述)-使用<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>Geolocation</title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <script src='https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.js'></script> <link href='https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.css' rel='stylesheet' /> <style> body { margin:0; padding:0; } #map { position:absolute; top:0; bottom:0; width:100%; } </style> </head> <body> <div id='map'></div> <a href='#' id='geolocate' class='ui-button'>Find me</a> <script> L.mapbox.accessToken = 'pk.eyJ1IjoidGltbGlzdGVuIiwiYSI6ImNqaWs5eWltbTAybG8za21zNjVuZjg5MW4ifQ.xCKtim61H1YXAkU5KT9-FQ'; var map = L.mapbox.map('map', 'mapbox.streets'); var myLayer = L.mapbox.featureLayer().addTo(map); // This uses the HTML5 geolocation API, which is available on // most mobile browsers and modern browsers, but not in Internet Explorer // // See this chart of compatibility for details: // http://caniuse.com/#feat=geolocation if (!navigator.geolocation) { geolocate.innerHTML = 'Geolocation is not available'; } else { map.locate(); } // Once we've got a position, zoom and center the map // on it, and add a single marker. map.on('locationfound', function(e) { map.fitBounds(e.bounds); myLayer.setGeoJSON({ type: 'Feature', geometry: { type: 'Point', coordinates: [e.latlng.lng, e.latlng.lat] }, properties: { 'title': 'Here I am!', 'marker-color': '#ff8888', 'marker-symbol': 'star' } }); // And hide the geolocation button geolocate.parentNode.removeChild(geolocate); }); // If the user chooses not to allow their location // to be shared, display an error message. map.on('locationerror', function() { geolocate.innerHTML = 'Position could not be found'; }); </script> </body> </html> 仅显示相关的时间窗口。

facet_wrap

选项2:使用ggplot(data = data, aes(x=Month, y=Oxygen)) + geom_point() + geom_smooth(method = "loess", se=FALSE) + facet_wrap( ~ Year, ncol=2, scales = 'free_x') + scale_x_date(date_breaks = "1 month", date_labels = "%B") + theme( axis.text.x=element_text(angle = 90, hjust = 1), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black") ) 作为x轴:

Month

我对日期的处理不多,所以这是一个技巧-但它可能足够好,直到/除非有人展示出一个好的解决方案。

ggplot(data = data, aes(x=Month, y=Oxygen)) + 
  geom_point() + 
  geom_smooth(method = "loess", se=FALSE) + 
  facet_wrap( ~ Year, ncol=2) + 
  scale_x_continuous(name = "Date", breaks = 1:12, labels = month.name) + 
  # scale_x_date(date_breaks = "1 month", date_labels = "%B")  + 
  theme(
    axis.text.x=element_text(angle = 90, hjust = 1),
    panel.grid.major = element_blank(), 
    panel.grid.minor = element_blank(),
    panel.background = element_blank(),
    axis.line = element_line(colour = "black")
  )