【问题标题】:How can I plot vertical and horizontal lines even when xpd=TRUE?即使 xpd=TRUE,我如何绘制垂直线和水平线?
【发布时间】:2017-12-23 05:05:23
【问题描述】:

这是一个简化的绘图:

env <- data.frame(site = c('BLK','DUC','WHP','BLK','DUC','WHP','BLK','DUC','WHP'),
                  sal = c(5,6,3,2,4,5,6,8,4),
                  date = c(2013,2013,2013,2015,2015,2015,2017,2017,2017))
sitelist <- c('BLK','DUC','WHP')
par(mar=c(3,5,3,6), xpd = T)
plot(sal~date, data = env, type = 'n', ylim = c(0,10), ylab = 'Salinity',
     bty = 'n', xlab = '')
abline(v=2016, col = 'khaki', lwd = 20)
abline(mean(env$sal), 0, lty = 3)
for (ii in seq_along(sitelist)) {
  i <- sitelist[ii]; lines(sal[site==i] ~ date[site==i], data = env,
                            col = c(4,2,5)[ii],  lwd = 2,
                            lty = c(1,2,3)[ii]);
  points(sal[site==i] ~ date[site==i], data = env,
         pch = c(0,1,2)[ii], col = c(4,2,5)[ii])}
legend('topright', title = 'sites', inset=c(-0.2,0), lty = c(1,2,3), 
       col = c(4,2,5), lwd = 2, sitelist, 
       pch = c(0,1,2))

正如所写,这段代码生成了一个绘图,其中abline 函数创建了超出绘图边界的线条,这要感谢xpd=T。但是,我不想设置xpd=F,因为我无法在边界之外绘制我的图例。解决方案必须是使用xpd=F 在边界之外绘制图例的方法,或者是绘制在边界处停止的线条的方法。理想情况下,该解决方案将使用基本程序并且相当标准,因此我可以将其放入我的大约 20 个地块中,而无需进行太多自定义。

我尝试使用segments,但对分段的圆形边缘不满意,因为我的垂直线应该是一种阴影区域以指示特定时间段。

【问题讨论】:

  • 为什么不在 abline 调用中设置 xpd=F?

标签: r plot


【解决方案1】:

您可以在 par 调用中将 xpd 设置为 FALSE,然后在 legend 调用中插入 xpd = TRUE,如下所示:

env <- data.frame(site = c('BLK','DUC','WHP','BLK','DUC','WHP','BLK','DUC','WHP'),
                  sal = c(5,6,3,2,4,5,6,8,4),
                  date = c(2013,2013,2013,2015,2015,2015,2017,2017,2017))
sitelist <- c('BLK','DUC','WHP')
par(mar=c(3,5,3,6), xpd = F)
plot(sal~date, data = env, type = 'n', ylim = c(0,10), ylab = 'Salinity',
     bty = 'n', xlab = '')
abline(v=2016, col = 'khaki', lwd = 20)
abline(mean(env$sal), 0, lty = 3)
for (ii in seq_along(sitelist)) {
  i <- sitelist[ii]; lines(sal[site==i] ~ date[site==i], data = env,
                            col = c(4,2,5)[ii],  lwd = 2,
                            lty = c(1,2,3)[ii]);
  points(sal[site==i] ~ date[site==i], data = env,
         pch = c(0,1,2)[ii], col = c(4,2,5)[ii])}
legend('topright', title = 'sites', inset=c(-0.2,0), lty = c(1,2,3), 
       col = c(4,2,5), lwd = 2, sitelist, 
       pch = c(0,1,2),
     xpd = T)

或者在 par 调用中保持 xpd = TRUE 并在 abline 调用中将 xpd 设置为 FALSE,如下所示:

env <- data.frame(site = c('BLK','DUC','WHP','BLK','DUC','WHP','BLK','DUC','WHP'),
                  sal = c(5,6,3,2,4,5,6,8,4),
                  date = c(2013,2013,2013,2015,2015,2015,2017,2017,2017))
sitelist <- c('BLK','DUC','WHP')
par(mar=c(3,5,3,6), xpd = T)
plot(sal~date, data = env, type = 'n', ylim = c(0,10), ylab = 'Salinity',
     bty = 'n', xlab = '')
abline(v=2016, col = 'khaki', lwd = 20,xpd=F)
abline(mean(env$sal), 0, lty = 3,xpd=F)
for (ii in seq_along(sitelist)) {
  i <- sitelist[ii]; lines(sal[site==i] ~ date[site==i], data = env,
                            col = c(4,2,5)[ii],  lwd = 2,
                            lty = c(1,2,3)[ii]);
  points(sal[site==i] ~ date[site==i], data = env,
         pch = c(0,1,2)[ii], col = c(4,2,5)[ii])}
legend('topright', title = 'sites', inset=c(-0.2,0), lty = c(1,2,3), 
       col = c(4,2,5), lwd = 2, sitelist, 
       pch = c(0,1,2))

【讨论】:

  • 感谢您提供直接的解决方案!我不知道xpd 可以在par() 之外使用。
【解决方案2】:

这应该可以解决您的问题。

替换

abline(v=2016, col = 'khaki', lwd = 20)
abline(mean(env$sal), 0, lty = 3)

lines(c(2013, 2017), rep(mean(env$sal), 2), col="black", lwd = 2, lty = 2)
lines(rep(2016, 2), c(0, 10), col="khaki", lwd = 20)

来源:https://stackoverflow.com/a/24741885/5874001

par(mar=c(3,5,3,6), xpd = T)
plot(sal~date, data = env, type = 'n', ylim = c(0,10), ylab = 'Salinity', bty = 'n', xlab = '')
lines(c(2013, 2017), rep(mean(env$sal), 2), col="black", lwd = 2, lty = 2)
lines(rep(2016, 2), c(0, 10), col="khaki", lwd = 20)
for (ii in seq_along(sitelist)) {
  i <- sitelist[ii]; lines(sal[site==i] ~ date[site==i], 
                            data = env,
                            col = c(4,2,5)[ii],  
                            lwd = 2,
                            lty = c(1,2,3)[ii]);
  points(sal[site==i] ~ date[site==i], data = env,
         pch = c(0,1,2)[ii], col = c(4,2,5)[ii])}
legend('topright',  title = 'sites', inset=c(-0.2,0), 
       lty = c(1,2,3), col = c(4,2,5), lwd = 2, 
       sitelist, pch = c(0,1,2))

如果您有 20 多个图,我会看看您是否可以编写一个循环来执行该任务。

【讨论】:

  • 横线呢?
  • 完成了,您的回答看起来也不错,而且信息量更大:)