提问人:dandrews 提问时间:10/13/2023 最后编辑:Axemandandrews 更新时间:10/14/2023 访问量:61
当数据中只有 0 时,您可以强制 y 轴从 0 开始吗 (ggplot)
Can you force the y axis to start at 0 when there is only 0's in the data (ggplot)
问:
我正在做一些数据探索,包括绘制时间序列。当我把数据拉下来时,有一些“结果”是真零。这些图包含许多站点,因此我使用 ggplot 的实用程序在多个站点上快速生成相同感兴趣参数的图形。我发现我可以强制 y 轴从这个堆栈帖子的 0 开始,但是当只有零值时,它会恢复为负 y 轴。facet_wrap
这里有一些代码,一个站点有零和非零数据(有效),另一个站点只有一个零,导致负 y 轴。
library(tidyverse)
dat <- structure(list(result = c(0, 0.01, 0, 0, 0.01, 0, 0, 0), date = structure(c(7755,
7769, 7783, 7796, 7832, 7888, 7888, 841), class = "Date"), param_name = c("TP_mgL",
"TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL"
), shortname = c("Black R. Boonville", "Black R. Boonville",
"Black R. Boonville", "Black R. Boonville", "Black R. Boonville",
"Black R. Boonville", "Black R. Boonville", "Independence R."
)), row.names = c(NA, -8L), class = c("tbl_df", "tbl", "data.frame"
), na.action = structure(c(`4` = 4L, `5` = 5L, `7` = 7L, `8` = 8L,
`9` = 9L, `11` = 11L, `12` = 12L, `13` = 13L, `14` = 14L, `21` = 21L,
`23` = 23L, `24` = 24L, `25` = 25L, `27` = 27L, `32` = 32L, `36` = 36L,
`53` = 53L, `54` = 54L, `55` = 55L, `57` = 57L, `58` = 58L, `60` = 60L,
`61` = 61L, `64` = 64L, `65` = 65L, `68` = 68L, `69` = 69L, `70` = 70L,
`72` = 72L, `73` = 73L, `85` = 85L, `104` = 104L, `105` = 105L,
`109` = 109L, `110` = 110L, `123` = 123L, `127` = 127L, `129` = 129L,
`130` = 130L, `135` = 135L, `136` = 136L, `137` = 137L, `138` = 138L,
`141` = 141L, `143` = 143L, `144` = 144L, `145` = 145L, `146` = 146L,
`151` = 151L, `153` = 153L, `154` = 154L, `155` = 155L, `156` = 156L,
`157` = 157L, `161` = 161L, `164` = 164L, `165` = 165L, `166` = 166L,
`172` = 172L, `178` = 178L, `179` = 179L, `184` = 184L, `208` = 208L,
`209` = 209L, `257` = 257L, `264` = 264L, `268` = 268L, `287` = 287L,
`292` = 292L, `293` = 293L, `295` = 295L, `296` = 296L, `297` = 297L,
`304` = 304L, `320` = 320L, `329` = 329L, `330` = 330L, `331` = 331L,
`332` = 332L, `333` = 333L, `334` = 334L, `335` = 335L, `336` = 336L,
`337` = 337L, `338` = 338L, `339` = 339L, `340` = 340L, `341` = 341L,
`343` = 343L, `344` = 344L, `349` = 349L, `350` = 350L, `351` = 351L,
`365` = 365L, `371` = 371L, `374` = 374L, `378` = 378L, `383` = 383L,
`390` = 390L, `391` = 391L, `397` = 397L, `400` = 400L, `401` = 401L,
`402` = 402L, `410` = 410L, `412` = 412L, `413` = 413L, `414` = 414L,
`415` = 415L, `416` = 416L, `417` = 417L, `418` = 418L, `419` = 419L,
`421` = 421L, `422` = 422L, `424` = 424L, `425` = 425L, `430` = 430L,
`431` = 431L, `446` = 446L, `451` = 451L, `452` = 452L, `457` = 457L,
`458` = 458L, `459` = 459L, `463` = 463L, `470` = 470L, `480` = 480L,
`493` = 493L, `494` = 494L, `496` = 496L, `498` = 498L, `499` = 499L,
`500` = 500L, `501` = 501L, `506` = 506L, `507` = 507L, `508` = 508L,
`512` = 512L, `513` = 513L, `514` = 514L, `515` = 515L, `516` = 516L,
`539` = 539L, `563` = 563L, `564` = 564L, `565` = 565L, `569` = 569L,
`570` = 570L, `571` = 571L, `574` = 574L, `575` = 575L, `581` = 581L,
`587` = 587L, `593` = 593L, `600` = 600L, `605` = 605L, `610` = 610L,
`750` = 750L, `761` = 761L, `776` = 776L, `837` = 837L, `855` = 855L,
`861` = 861L, `881` = 881L), class = "omit"))
ggplot(dat) +
geom_point(aes(x=date,y=result,color=param_name),
pch=19) +
scale_y_continuous(limits = c(0,NA)) +
theme_bw() +
theme(element_blank()) +
facet_wrap(facets = ~shortname,
scales = 'free') +
scale_x_date(date_labels = '%y') +
theme(legend.position = 'none') +
xlab('Year') +
ylab(expression(paste('Total Phosphorus (',mu,'/g/l)')))
我试过 and,但都没有强制单个零图从 0 开始。想知道是否有任何方法可以实现这一目标?expand_limits(y=0)
scale_y_continuous(limits=c(0,NA))
编辑多亏了 Seth 的评论,我意识到我的问题存在一个陷阱。在实际数据中,数据在 y 方向上的范围足够大,因此我需要保持 y 刻度自由。Seth 的一个很好的解决方案是只释放 x 尺度,以便在代码中实现:facet_wrap
facet_wrap(facets~shortname,
scales='free_x')
有效,但随后来自站点的大部分数据都与 X 轴相撞。
答:
原始答案
我们可以有选择地只释放 x 轴。面板将共享一个公共 y 轴,任何仅点为 0 的面板仍将受到其他数据范围的约束。facets
在 中,设置 ,您可以删除 。facet_wrap
scales = "free_x"
scale_y_continuous
library(tidyverse)
ggplot(dat) +
geom_point(aes(x=date,y=result,color=param_name),
pch=19) +
theme_bw() +
theme(element_blank()) +
facet_wrap(facets = ~shortname,
scales = 'free_x') +
scale_x_date(date_labels = '%y') +
theme(legend.position = 'none') +
xlab('Year') +
ylab(expression(paste('Total Phosphorus (',mu,'/g/l)')))
更新的答案
使用它可以指定每个面的比例,并且该软件包提供了几种方法来解决这个问题。ggh4x
对于此示例,我在提供的示例中添加了一些虚假数据,并在末尾包含这些数据。
我首先创建一个列表,列出我想要应用 y 轴限制的列表。在函数中,添加的是我应用指定 .我选择使用全范围的 ,但您可以根据需要进行调整。shortnames
ggplot
scale_y_facet
limit
result
library(tidyverse)
library(ggh4x)
zero_dat <- dat %>%
filter(sum(abs(result)) == 0, .by = shortname) %>% pull(shortname)
ggplot(dat) +
geom_point(aes(x=date,y=result,color=param_name),
pch=19) +
theme_bw() +
theme(element_blank()) +
facet_wrap(facets = ~shortname,
scales = 'free') +
scale_x_date(date_labels = '%y') +
scale_y_facet(
shortname %in% zero_dat,
limits = range(dat$result)) +
theme(legend.position = 'none') +
xlab('Year') +
ylab(expression(paste('Total Phosphorus (',mu,'/g/l)')))
数据
dat <- structure(list(result = c(0, 0.01, 0, 0, 0.01, 0, 0, 0, 4, 1,
5, 10, 0), date = structure(c(7755, 7769, 7783, 7796, 7832, 7888,
7888, 841, 7755, 8160, 8192, 8770, 9494), class = "Date"), param_name = c("TP_mgL",
"TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL",
"TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL", "TP_mgL"), shortname = c("Black R. Boonville",
"Black R. Boonville", "Black R. Boonville", "Black R. Boonville",
"Black R. Boonville", "Black R. Boonville", "Black R. Boonville",
"Independence R.", "Fake Data", "Fake Data", "Fake Data", "Fake Data",
"Fake Data")), row.names = c(NA, -13L), class = c("tbl_df", "tbl",
"data.frame"), na.action = structure(c(`4` = 4L, `5` = 5L, `7` = 7L,
`8` = 8L, `9` = 9L, `11` = 11L, `12` = 12L, `13` = 13L, `14` = 14L,
`21` = 21L, `23` = 23L, `24` = 24L, `25` = 25L, `27` = 27L, `32` = 32L,
`36` = 36L, `53` = 53L, `54` = 54L, `55` = 55L, `57` = 57L, `58` = 58L,
`60` = 60L, `61` = 61L, `64` = 64L, `65` = 65L, `68` = 68L, `69` = 69L,
`70` = 70L, `72` = 72L, `73` = 73L, `85` = 85L, `104` = 104L,
`105` = 105L, `109` = 109L, `110` = 110L, `123` = 123L, `127` = 127L,
`129` = 129L, `130` = 130L, `135` = 135L, `136` = 136L, `137` = 137L,
`138` = 138L, `141` = 141L, `143` = 143L, `144` = 144L, `145` = 145L,
`146` = 146L, `151` = 151L, `153` = 153L, `154` = 154L, `155` = 155L,
`156` = 156L, `157` = 157L, `161` = 161L, `164` = 164L, `165` = 165L,
`166` = 166L, `172` = 172L, `178` = 178L, `179` = 179L, `184` = 184L,
`208` = 208L, `209` = 209L, `257` = 257L, `264` = 264L, `268` = 268L,
`287` = 287L, `292` = 292L, `293` = 293L, `295` = 295L, `296` = 296L,
`297` = 297L, `304` = 304L, `320` = 320L, `329` = 329L, `330` = 330L,
`331` = 331L, `332` = 332L, `333` = 333L, `334` = 334L, `335` = 335L,
`336` = 336L, `337` = 337L, `338` = 338L, `339` = 339L, `340` = 340L,
`341` = 341L, `343` = 343L, `344` = 344L, `349` = 349L, `350` = 350L,
`351` = 351L, `365` = 365L, `371` = 371L, `374` = 374L, `378` = 378L,
`383` = 383L, `390` = 390L, `391` = 391L, `397` = 397L, `400` = 400L,
`401` = 401L, `402` = 402L, `410` = 410L, `412` = 412L, `413` = 413L,
`414` = 414L, `415` = 415L, `416` = 416L, `417` = 417L, `418` = 418L,
`419` = 419L, `421` = 421L, `422` = 422L, `424` = 424L, `425` = 425L,
`430` = 430L, `431` = 431L, `446` = 446L, `451` = 451L, `452` = 452L,
`457` = 457L, `458` = 458L, `459` = 459L, `463` = 463L, `470` = 470L,
`480` = 480L, `493` = 493L, `494` = 494L, `496` = 496L, `498` = 498L,
`499` = 499L, `500` = 500L, `501` = 501L, `506` = 506L, `507` = 507L,
`508` = 508L, `512` = 512L, `513` = 513L, `514` = 514L, `515` = 515L,
`516` = 516L, `539` = 539L, `563` = 563L, `564` = 564L, `565` = 565L,
`569` = 569L, `570` = 570L, `571` = 571L, `574` = 574L, `575` = 575L,
`581` = 581L, `587` = 587L, `593` = 593L, `600` = 600L, `605` = 605L,
`610` = 610L, `750` = 750L, `761` = 761L, `776` = 776L, `837` = 837L,
`855` = 855L, `861` = 861L, `881` = 881L), class = "omit"))
评论
scale_y_continuous
facet_wrap
scales = "free_x"