IMP researchR plot

10.ggplot2——坐标轴和刻度位置(二)

2021-11-26  本文已影响0人  denghb001

10.2 Date-time

10.2.1 Breaks

当图形属性映射到日期/时间类型时会出现一种特殊情况:例如基本的Date(用于日期)和POSIXct(用于日期时间)类,以及hms包提供的“时间”值类. 如果您的日期格式不同,您需要使用as.Date()as.POSIXct()hms::as_hms()来转换它们。您可能还会发现 lubridate 包有助于操作日期/时间数据。

假设您已经对映射到x图形属性的数据进行了适当的格式化,ggplot2将使用scale_x_date()作为日期的默认比例,并使用scale_x_datetime()作为日期时间数据的默认比例。其他图形属性的相应尺度遵循通常的命名规则。日期尺度的行为类似于其他连续尺度,但包含允许您在日期友好单位中工作的附加参数。

date_breaks参数允许您按日期单位(年、月、周、日、小时、分钟和秒)定点中断。例如,date_breaks = "2 weeks"每两周放置一个主要刻度线,date_breaks = 25 years"每 25 年放置一次:

date_base <- ggplot(economics, aes(date, psavert)) + 
  geom_line(na.rm = TRUE) +
  labs(x = NULL, y = NULL)

date_base 
date_base + scale_x_date(date_breaks = "25 years")
image.png

注意到在内部date_breaks = "25 years"被视为breaks = scales::breaks_width("25 years"). 较长的形式通常是不必要的,但如果你希望指定一个offset. 假设目标是从 1900 年 1 月 1 日开始,我们希望以 25 年为间隔设置中断。指定date_breaks = "25 years"以下列方式产生中断:

century20 <- as.Date(c("1900-01-01", "1999-12-31"))
breaks <- scales::breaks_width("25 years")
breaks(century20)
#> [1] "1900-01-01" "1925-01-01" "1950-01-01" "1975-01-01" "2000-01-01"

由于从1900年 1 月 1 日开始,并且中断在全年值中递增,因此生成的每个中断日期都落在 1 月 1 日。我们可以通过设置将所有这些休息时间移动到 2 月 1 日offset = 31(因为1 月有 31 天)。

10.2.2 次要中断(Minor breaks)

对于日期/时间刻度,您可以使用date_minor_breaks参数:

date_base + scale_x_date(
  limits = as.Date(c("2003-01-01", "2003-04-01")),
  date_breaks = "1 month"
)

date_base + scale_x_date(
  limits = as.Date(c("2003-01-01", "2003-04-01")),
  date_breaks = "1 month",
  date_minor_breaks = "1 week"
)
image.png

请注意,在第一个图中,次要中断在每月主要中断之间均匀分布。在第二个图中,大中断和小中断的模式略有不同:小断点总是相隔 7 天,但大断点相隔 1 个月。由于月份的长度不同,这会导致间距略有不均匀。

10.2.3 标签(Labels)

10.2.4 日期刻度标签

date_break一样,日期尺度也包含一个date_labels参数。它使用与strptime()format()相同的格式化字符串控制标签的显示。例如,要显示14/10/1979这样的日期,您可以使用字符串“%d/%m/%Y”:在这个表达式中,%d产生一个数字日期,%m产生一个数字月份,而%Y产生一个四位数字年份。下表提供了格式化字符串列表:

字符串 含义
%S 秒 (00-59)
%M 分钟 (00-59)
%l 小时,12 小时制 (1-12)
%I 小时,12 小时制 (01-12)
%p 上午下午
%H 小时,24 小时制 (00-23)
%a 星期几,缩写(周一至周日)
%A 星期几,全称(周一至周日)
%e 每月的第几天 (1-31)
%d 每月的第几天 (01-31)
%m 月份,数字 (01-12)
%b 月份,缩写(Jan-Dec)
%B 月,全称(1 月至 12 月)
%y 年,无世纪 (00-99)
%Y 年,世纪 (0000-9999)

日期标签格式的一个有用场景是,当没有足够的空间来指定四位数年份时,使用%y确保只显示最后两位数字:

base <- ggplot(economics, aes(date, psavert)) + 
  geom_line(na.rm = TRUE) +
  labs(x = NULL, y = NULL)

base + scale_x_date(date_breaks = "5 years")
base + scale_x_date(date_breaks = "5 years", date_labels = "%y")
image.png

在格式化字符串中包含换行符\n会很有用,尤其是在包含全长月份名称时:

lim <- as.Date(c("2004-01-01", "2005-01-01"))

base + scale_x_date(limits = lim, date_labels = "%b %y")
base + scale_x_date(limits = lim, date_labels = "%B\n%Y")
image.png

在这些示例中,我通过date_labels参数手动指定了标签。另一种方法是将标签函数传递给labels参数。scales 包提供了两个方便的功能,可以为您生成日期标签:

image.png

10.3 离散型数据

也可以将离散变量映射到位置比例,在这种情况下,默认比例是scale_x_discrete()scale_y_discrete()。例如,以下两个绘图规范是等效的

ggplot(mpg, aes(x = hwy, y = class)) + 
  geom_point()

ggplot(mpg, aes(x = hwy, y = class)) + 
  geom_point() + 
  scale_x_continuous() +
  scale_y_discrete()

在内部,ggplot2 通过将每个类别映射到一个整数值然后在相应的坐标位置绘制几何来处理离散比例。为了说明这一点,我们可以在图中添加一个自定义注释:

ggplot(mpg, aes(x = hwy, y = class)) + 
  geom_point() +
  annotate("text", x = 5, y = 1:7, label = 1:7)
image

10.3.1 限制(Limits)

10.3.2 刻度标签

当数据是分类数据时,您还可以选择使用命名向量来设置与特定值关联的标签。这允许您更改某些标签而不是其他标签,而无需更改顺序或中断:

base <- ggplot(toy, aes(const, txt)) + 
  geom_point() +
  labs(x = NULL, y = NULL)

base
base + scale_y_discrete(labels = c(c = "carrot", b = "banana"))
image.png

它还包含与其他类型数据相关的函数,例如scales::label_wrap()允许您跨行包装长字符串。

10.3.3 guide_axis()

指南函数主要用于控制图例,但是由于图例和坐标轴都是Guide类型,ggplot2还为坐标轴提供了一个guide_axis()函数。它的主要目的是提供额外的控制来防止标签重叠:

base <- ggplot(mpg, aes(manufacturer, hwy)) + geom_boxplot() 

base + guides(x = guide_axis(n.dodge = 3))
base + guides(x = guide_axis(angle = 90))
image.png

10.4 分箱

离散位置尺度的变化是分箱尺度,其中连续变量被分割成多个分箱,并绘制离散变量。例如,如果我们想修改上面的图以显示每个位置的观察数量,我们可以使用geom_count()而不是geom_point(),这样点的大小与观察数量成比例。如下左图所示,这是一个改进,但仍然相当混乱。为了改善这一点,右边图形使用scale_x_binned()hwy值在传递给geom之前切成10个bins:

base <- ggplot(mpg, aes(hwy, class)) + geom_count()

base 
base + scale_x_binned(n.breaks = 10)
image.png

10.5 限制(Limits)

所有缩放都有定义比例尺所处领域的限制,这些限制通常来自于数据的范围。在这里,我们将讨论为什么你可能想要指定限制而不是依赖于数据:

  1. 您想缩小限制,专注于绘图的一个有趣区域。
  2. 您想要扩展限制,使多个图匹配或匹配变量的自然限制(例如百分比从 0 到 100)。

考虑位置缩放的局限性是很自然的:它们直接映射到坐标轴的范围。但limits也适用于具有图例的缩放,如颜色、大小和形状,如果你想在多个图形中保持颜色一致,这些限制就特别重要。

使用limits参数修改限制:

下面显示了一个最小的例子。在左侧面板中,x 比例的限制设置为默认值(数据范围),中间面板扩展限制,右侧面板缩小它们:

df <- data.frame(x = 1:3, y = 1:3)
base <- ggplot(df, aes(x, y)) + geom_point() 

base
base + scale_x_continuous(limits = c(0, 4))
base + scale_x_continuous(limits = c(1.5, 2.5))
#> Warning: Removed 2 rows containing missing values (geom_point).
image.png

10.5.1 设置多个限制

当您需要确保不同图中的缩放彼此一致时,手动设置缩放限制是一项常见任务。当您创建分面图时,ggplot2 会自动为您执行此操作:

ggplot(mpg, aes(displ, hwy, colour = fl)) + 
  geom_point() +
  facet_wrap(vars(year))
image

(颜色代表燃料类型,可以是R(普通的),e(乙醇),d(柴油),p(高级)或C(压缩天然气) )

在此图中,x 轴和 y 轴在两个方面具有相同的限制并且颜色一致。但是,有时需要在多个图之间保持一致性,这通常具有导致每个图独立设置比例限制的不良特性:

mpg_99 <- mpg %>% filter(year == 1999)
mpg_08 <- mpg %>% filter(year == 2008)

base_99 <- ggplot(mpg_99, aes(displ, hwy, colour = fl)) + geom_point() 
base_08 <- ggplot(mpg_08, aes(displ, hwy, colour = fl)) + geom_point() 

base_99
base_08
image.png

每个图形本身都有意义,但两者之间的视觉比较是困难的。轴限制是不同的,因为 1998 年的数据中只表示普通、优质和柴油燃料,所以颜色映射不一致。

base_99 + 
  scale_x_continuous(limits = c(1, 7)) +
  scale_y_continuous(limits = c(10, 45))

base_08 + 
  scale_x_continuous(limits = c(1, 7)) +
  scale_y_continuous(limits = c(10, 45))
image.png

在许多情况下,设置 x 和 y 轴的限制就足以解决问题,但在本例中,我们仍然需要确保各图的色标一致。

base_99 + 
  scale_x_continuous(limits = c(1, 7)) +
  scale_y_continuous(limits = c(10, 45)) +
  scale_color_discrete(limits = c("c", "d", "e", "p", "r"))

base_08 + 
  scale_x_continuous(limits = c(1, 7)) +
  scale_y_continuous(limits = c(10, 45)) +
  scale_color_discrete(limits = c("c", "d", "e", "p", "r"))
image.png

请注意,因为燃料变量fl是离散的,颜色属性的限制是可能值的向量,而不是两个端点。

因为修改比例限制是一项很常见的任务,ggplot2 提供了一些方便的函数来使这更容易。对于位置缩放xlim()ylim()辅助函数检查它们的输入,然后分别为 x 和 y 轴指定适当的缩放。结果取决于秤的类型:

为了确保在前面的示例中一致的轴缩放,我们可以使用这些辅助函数:

base_99 + xlim(1, 7) + ylim(10, 45)
base_08 + xlim(1, 7) + ylim(10, 45)
image.png

设置限制的另一个选项是lims()将名称-值对作为输入的函数,其中名称指定美感,值指定限制:

base_99 + lims(x = c(1, 7), y = c(10, 45), colour = c("c", "d", "e", "p", "r"))
base_08 + lims(x = c(1, 7), y = c(10, 45), colour = c("c", "d", "e", "p", "r"))
image.png
上一篇下一篇

猜你喜欢

热点阅读