r - 使用 facet_grid 在 ggplot 中自动设置数据代表中断
问题描述
这是从R Graph Gallery中获取的可复制示例:
library(ggplot2)
library(dplyr)
library(viridis)
library(Interpol.T)
library(lubridate)
library(ggExtra)
library(tidyr)
data <- data(Trentino_hourly_T,package = "Interpol.T")
names(h_d_t)[1:5]<- c("stationid","date","hour","temp","flag")
df <- as_tibble(h_d_t) %>%
filter(stationid =="T0001")
df$date<-ymd(df$date)
df <- df %>% mutate(date = ymd(date),
year = year(date),
month = month(date, label=TRUE),
day = day(date))
rm(list=c("h_d_t","mo_bias","Tn","Tx",
"Th_int_list","calibration_l",
"calibration_shape","Tm_list"))
df <- df %>%
filter(between(date, as.Date("2004-02-13"), as.Date("2004-04-29")) | between(date, as.Date("2005-02-13"), as.Date("2005-04-29")))
df <-df %>% select(stationid,day,hour,month,year,temp)%>%
fill(temp)
statno <-unique(df$stationid)
######## Plotting starts here#####################
p <-ggplot(df, aes(day,hour,fill=temp))+
geom_tile(color= "white",size=0.1) +
scale_fill_viridis(name="Hrly Temps C",option ="C") +
facet_grid(year~month, scales = "free") +
scale_y_continuous(trans = "reverse", breaks = unique(df$hour)) +
theme_minimal(base_size = 8) +
labs(title= paste("Hourly Temps - Station",statno), x="Day", y="Hour Commencing") +
theme(legend.position = "bottom",
plot.title=element_text(size = 14, hjust = 0),
axis.text.y=element_text(size=6),
strip.background = element_rect(colour="white"),
axis.ticks=element_blank(),
axis.text=element_text(size=7),
legend.text=element_text(size=6))+
removeGrid()
困扰我的是,x 轴中断没有明确显示每个月的第一天和最后一天,更糟糕的是,它们显示了 2 月 30 日、3 月 0 日和 4 月 0 日。
我的目标是使用一个函数来自动和明确地显示每个绘制月份的真实第一天和最后一天(在示例中为 2 月 13 日 - 2 月 29 日、3 月 1 日 - 3 月 31 日和 4 月 1 日 - 4 月 29 日),其中包含 4 到 6 次休息每一个月。
由于此图将显示在闪亮的应用程序中,用户可以在其中更改绘制的时间段,因此解决方案确实需要自动化。
以下是我尝试过的一些事情:
library(scales)
p + scale_x_continuous(breaks =breaks_pretty())
我试图编写自己的函数,但发生了可怕的事情:
breaksFUN <- function(x){
round(seq(min(x), max(x), length.out = 5), 0)
}
p + scale_x_continuous(breaks =breaksFUN)
先感谢您。
解决方案
感谢 Axeman 的贡献,它真的很有帮助!它适用于我的示例,但我在数据中尝试它时遇到了一些问题。但是,我对其进行了修改,现在它可以正常工作,这是我受 Axeman 启发的解决方案:
breaksFUN <- function(x) {
s <- round(c(seq(min(x) + 1.5, max(x) - 5.5, length.out = 4), max(x) - 1.5))
s[s == 0] <- 1
s[s > 31] <- 31
s <- round(seq(range(s)[1], range(s)[2], length.out = 5))
unique(s)
}
p + scale_x_continuous(breaks = breaksFUN)
推荐阅读
- python - 如何使用 Python 和 BeautifulSoup 访问检查中显示的特定表以进行网络抓取
- reactjs - 如何在 NextJS 项目中填充 IE11?
- mysql - Spring Boot Hibernate ManyToMany Relation 使用嵌入式模型
- python - 根据列的(字符串)内容将一行分成多行
- mysql - 选择更改其最后值的记录
- python - 在 Python 中使用 to_excel 函数时如何删除空行
- json - 在 Flutter 中解析 JSON 会导致对象字段的 NULL 值
- python-3.x - Python - 多行文本解析器
- python - 我试图编写一个循环问题的程序,直到用户停止输入,但我不断收到无效的语法错误
- excel - Excel VBA - 取消隐藏行会清除它们的格式