【问题标题】:Change line width in ggplot, not size更改ggplot中的线宽,而不是大小
【发布时间】:2019-03-23 22:14:19
【问题描述】:

我在 ggplot 中看到了几篇关于 changing line width 的帖子。答案虽然对 OP 来说信息丰富且有效,但改变了 size 行。也就是说,ggplot 似乎将线条视为一系列单位,而 size 增加了每个单位的长度和宽度,使其他调整更粗略。

我希望有一种方法可以使线条更宽(更粗),而不会影响长度,进而影响破折号的比例。

我从https://cran.r-project.org/web/packages/ggplot2/vignettes/ggplot2-specs.html借了一些代码来说明我的意思:

library(ggplot2)

#A simple plot with manually set dashes.
#The first numeral is units of dash length, the second units in the gap in hexadecimal. 
lty <- c("11", "18", "1f", "81", "88", "8f", "f1", "f8", "ff")
linetypes <- data.frame(y = seq_along(lty), lty = lty) 

ggplot(linetypes, aes(0, y)) + 
  geom_segment(aes(xend = 5, yend = y, linetype = lty)) + 
  scale_linetype_identity() + 
  geom_text(aes(label = lty), hjust = 0, nudge_y = 0.2) +
  scale_x_continuous(NULL, breaks = NULL) + 
  scale_y_reverse(NULL, breaks = NULL)

#Altering the size changes the line width AND dash spacing.

ggplot(linetypes, aes(0, y)) + 
  geom_segment(aes(xend = 5, yend = y, linetype = lty), 
     size = 3) + 
  scale_linetype_identity() + 
  geom_text(aes(label = lty), hjust = 0, nudge_y = 0.3) +
  scale_x_continuous(NULL, breaks = NULL) + 
  scale_y_reverse(NULL, breaks = NULL)

基本上我想要的是粗线,相对较细和精细调整的间隙。我认为这是以另一种方式提出的同一个问题:有没有办法让所有的线条,比如说,“虚线”在宽度上有所不同,但在破折号的相对位置上没有?像这样(我完全伪造):

【问题讨论】:

标签: r ggplot2


【解决方案1】:

来自“线型规范”的?par 帮助文件(为强调而添加了粗体):

线类型可以通过给一个小的索引来指定 内置线型表(1 = 实线,2 = 虚线等,请参阅lty 以上)或直接作为开/关线段的长度。 这是通过一串偶数(最多 8 个) 字符,即 非零(十六进制)数字 字符串中连续位置的长度。例如, 字符串"33" 指定三个单位打开,然后是三个关闭和 "3313" 指定三个单位 on 后跟三个 off 后跟 一开,三关。这里的“单位”是(在大多数设备上) 与lwd 成正比,与lwd = 1 以像素或点为单位或 1/96 英寸。

这表明,如果我们指定适当变化的线型和线宽(例如,较粗的线是较细的线的两倍宽,开关延伸的长度是一半),我们可以实现看似相同的虚线的预期效果不同线宽下的长度。

注意:线型规范中允许的字符是c(1:9, "A":"F")),这意味着最短的可能拉伸长度是1个单位,而最长的是15个单位。这限制了可以创建的不同行的数量。

它与基本的 R 绘图函数按预期工作:

plot.new()
plot.window(xlim=c(0, 5), ylim=c(1, 3))
abline(h = 3, lty = "22", lwd = 8)
abline(h = 2, lty = "44", lwd = 4)
abline(h = 1, lty = "88", lwd = 2)
axis(2, at = 3:1, labels=c("22", "44", "88"), tick = FALSE, las = 1)

另一方面,对于 ggplot2,据我所知,图形文件设备的选择很重要。对于基于 vector 的设备,破折号整齐地对齐,但对于基于 bitmap 的设备则不一定:

p <- ggplot(data.frame(y = seq(1, 3),
                       lty = c("11", "22", "44"),
                       lwd = c(8, 4, 2)), 
            aes(0, y)) + 
  geom_segment(aes(xend = 5, yend = y, 
                   linetype = lty,
                   lwd = lwd)) + 
  geom_text(aes(label = lty), hjust = 0, nudge_x = -0.3) +

  scale_linetype_identity() + 
  scale_size_identity() +
  scale_x_continuous(NULL, breaks = NULL) + 
  scale_y_reverse(NULL, breaks = NULL, expand = c(0.5, 0))

# bitmap devices
ggsave("test.bmp", p + ggtitle(".bmp"))
ggsave("test.jpg", p + ggtitle(".jpg"))
ggsave("test.png", p + ggtitle(".png"))
ggsave("test.tiff", p + ggtitle(".tiff"))
ggsave("test.wmf", p + ggtitle(".wmf"))

# vector devices
ggsave("test.eps", p + ggtitle(".eps"))
ggsave("test.pdf", p + ggtitle(".pdf"))
ggsave("test.svg", p + ggtitle(".svg"))

我还没有在 ggplot2 中找到任何直接解决此问题的方法。不过,如果您需要其中一种位图格式,但相同间隔的破折号是重中之重,您可以先将绘图输出到其中一个基于矢量的设备,然后再从一种文件格式转换为另一种文件格式。

【讨论】:

  • 感谢您提供有用的信息!但它也向我暗示,我的问题没有解决方案。使用十六进制数字自定义 lty 并忽略点破折号,您可以拥有 15^2 = 225 个破折号/空格组合。听起来很棒!但是,如果你加宽线,它很快就会在使线清晰可见和保持 lty 数字足够低以至于它最终看起来不像我的第二个数字的下半部分,即糟糕之间,很快就变成了一种尴尬的平衡行为。我只是在学习 ggplot,所以我很欣赏这种洞察力!
猜你喜欢
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多