本文介绍了ggplot2:用图例制作多行+色带的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用

  • 多行
  • 每个都有一个环绕的功能区,
  • 具有用户指定的颜色
  • 并带有显示线条颜色和色带颜色的图例.

(向下滚动以查看几乎达到我所寻求的情节的示例.)我看到了相关的问题,但没有一个问题可以同时解决所有这些问题,并且我在网上寻找示例,但找不到类似的问题.我是ggplot2的新手,所以对这样的基本问题表示歉意,但也许您的回答也会对其他人有所帮助.

(Scroll down to see an example of a plot that almost achieves what I seek.)I've seen related questions but none that address all these issues together, and I've looked for examples online but can't find any like this. I'm brand new to ggplot2, so apologies for such a basic question but maybe your answer will help others too.

这是一个非常拙劣的尝试,将一张几乎可以完成我想要的图拼凑在一起的完整示例.我已经尝试过使用宽格式数据和长格式数据.(是的,我使用 = 而不是<-,并且我不使用很多建议的空格,但这是单独的问题...:-)

Here's a complete example of terribly inelegant attempts to cobble together a graph that almost accomplishes what I want. I've tried with both wide-format data and with long-format data. (And yes, I use = instead of <-, and I don't use spaces as many recommend, but those are separate issues... :-)

# Housekeeping:
graphics.off()
library("ggplot2")
library("tidyr") # for pivot_longer()

# Set up data:
set.seed(47405)
x = 1:10
y1 = 1 + 0.1*x + rnorm(length(x),0,0.2)  # line 1
y2 = 2 + 0.2*x + rnorm(length(x),0,0.2)  # line 2
y1lo = y1 - 0.2  # ribbon 1 low
y1hi = y1 + 0.2  # ribbon 1 high
y2lo = y2 - 0.3  # ribbon 2 low
y2hi = y2 + 0.3  # ribbon 2 high

# Wide format data frame:
wideDF = data.frame( x=x ,
                     y1lo=y1lo , y1=y1 , y1hi=y1hi ,
                     y2lo=y2lo , y2=y2 , y2hi=y2hi )

# Long format data frame:
longDF = pivot_longer( wideDF , cols=!x , names_to="line" , values_to="y" )
longDF$fill = NA
longDF$fill[grep( "1" , longDF$line  )] = "y1"
longDF$fill[grep( "2" , longDF$line  )] = "y2"

使用宽格式但没有图例的优雅方式:

An inelegant way using wide-format, but with no legend:

ggplot( wideDF , aes(x=x) ) +
  geom_ribbon( aes( ymin=y1lo , ymax=y1hi ) , fill="pink" , alpha=0.5 ) +
  geom_line( aes( y=y1 ) , col="red" ) +
  geom_ribbon( aes( ymin=y2lo , ymax=y2hi ) , fill="lightblue" , alpha=0.5 ) +
  geom_line( aes( y=y2 ) , col="blue" ) +
  labs( title="Using WIDE data frame" , y="Y label" , x="X label" ) +
  geom_text( x = max(wideDF$x) ,
             y = wideDF$y1[wideDF$x==max(wideDF$x)] ,
             hjust = 1 , vjust = -0.5 ,
             label="Y1" , color = "red" ) +
  geom_text( x = max(wideDF$x) ,
             y = wideDF$y2[wideDF$x==max(wideDF$x)] ,
             hjust = 1 , vjust = -0.5 ,
             label="Y2" , color = "blue" )

使用长格式的优雅方式,但仍然没有图例:

An inelegant way using long-format, still with no legend:

ggplot( ) +
  xlim(range(longDF$x)) + ylim(range(longDF$y)) +
  geom_ribbon( aes( x=longDF$x[longDF$line=="y1"] ,
                    ymin=longDF$y[longDF$line=="y1lo"] ,
                    ymax=longDF$y[longDF$line=="y1hi"] ),
               fill="pink" , alpha=0.5  ) +
  geom_line( aes( x=longDF$x[longDF$line=="y1"] ,
                  y=longDF$y[longDF$line=="y1"] ) ,
             color="red" ) +
  geom_ribbon( aes( x=longDF$x[longDF$line=="y2"] ,
                    ymin=longDF$y[longDF$line=="y2lo"] ,
                    ymax=longDF$y[longDF$line=="y2hi"] ),
               fill="lightblue" , alpha=0.5  ) +
  geom_line( aes( x=longDF$x[longDF$line=="y2"] ,
                  y=longDF$y[longDF$line=="y2"] ) ,
             color="blue" ) +
  labs( title="Using LONG data frame" , y="Y label" , x="X label" ) +
  geom_text( aes(
             x = max(longDF$x) ,
             y = longDF$y[longDF$x==max(longDF$x) & longDF$line=="y1"] ) ,
             hjust = 1 , vjust = -0.5 ,
             label="Y1" , color = "red" ) +
  geom_text( aes( x = max(longDF$x) ,
             y = longDF$y[longDF$x==max(longDF$x) & longDF$line=="y2"] ) ,
             hjust = 1 , vjust = -0.5 ,
             label="Y2" , color = "blue" )

所以,我的问题:

  1. 如何有效地编码多个线+色带图?上面的代码非常优雅,我显然缺少关于ggplot2中的 aes() data = 的基本概念.不仅显示代码而且简要解释 aes()发生了什么的答案都很棒.

  1. How can multiple line+ribbon graphs be coded efficiently? The code above is very inelegant, and I'm obviously missing fundamental concepts regarding aes() and data= in ggplot2. Answers that not only show code but also briefly explain what's going on with aes() would be awesome.

如何将图例添加到这些图中?(当然,有了图例,不需要上面的示例中的geom_text()元素.)

How can a legend be added to these plots? (Of course, with a legend, do not need geom_text() elements as in the examples above.)

对于ggplot中的多条线+色带图,使用宽格式或长格式数据帧更有用吗?

For multiple line+ribbon plots in ggplot, is in more useful to have wide-format or long-format data frames?

谢谢!

推荐答案

也许这就是您要寻找的...

Maybe this is what you are looking for ...

  1. 一般课程:如果您想要一个传奇,则必须在美学上映射一些东西,即将 color 和/或 fill 放在 aes()

您的宽数据集和长数据集都不适合进行简单绘图.相反,从长df开始,我首先摆脱了行列中的数字,并使数据集更宽,因此我们只有 y ymin ymax(这样做之后,我们得到的数据整齐,因为1和2是一个变量的类别,而y,ymin,ymax是不同的变量).这使我们可以仅使用两个geom图层来设置您的绘图.另外,我们不必使用复杂且易于出错的代码,例如 longDF $ x [longDF $ line =="y2"] 即可获得我们想要绘制的值.

Neither your wide nor your long dataset are suitable for easy plotting. Instead, starting from your long df, I first get rid of the numbers in your line column and make the dataset wider so we have just y, ymin, ymax (after doing so we end up with tidy data, as 1 and 2 are categories of one variabale, while y, ymin, ymax are different variables). This allows us to set up your plot with only two geom layers. Additonally we don't have to use complicated and error prone codelike longDF$x[longDF$line=="y2"] to get the values we like to plot.

对于文本标签,我使用 group_by(longDF1,fill)%>%top_n(1,x)作为数据,该数据只是为顶部x值的每一行选择行

For the text labels I use group_by(longDF1, fill) %>% top_n(1, x) as data which simply picks the rows for each line with the top x value.

最后,要获得正确的颜色,请通过 scale_xxx_manual

Finally, to get the colors right set them via scale_xxx_manual

library(dplyr)
library("ggplot2")
library("tidyr") # for pivot_longer()

# Set up data:
set.seed(47405)
x = 1:10
y1 = 1 + 0.1*x + rnorm(length(x),0,0.2)  # line 1
y2 = 2 + 0.2*x + rnorm(length(x),0,0.2)  # line 2
y1lo = y1 - 0.2  # ribbon 1 low
y1hi = y1 + 0.2  # ribbon 1 high
y2lo = y2 - 0.3  # ribbon 2 low
y2hi = y2 + 0.3  # ribbon 2 high

# Wide format data frame:
wideDF = data.frame( x=x ,
                     y1lo=y1lo , y1=y1 , y1hi=y1hi ,
                     y2lo=y2lo , y2=y2 , y2hi=y2hi )

# Long format data frame:
longDF = pivot_longer( wideDF , cols=!x , names_to="line" , values_to="y" )
longDF$fill = NA
longDF$fill[grep( "1" , longDF$line  )] = "y1"
longDF$fill[grep( "2" , longDF$line  )] = "y2"

longDF1 <- longDF %>%
  mutate(line = gsub("\\d", "", line)) %>%
  pivot_wider(id_cols = c(x, fill), names_from = line, values_from = y)

ggplot(longDF1) +
  geom_ribbon(aes(x=x, ymin=ylo, ymax=yhi, fill = fill), alpha=0.5) +
  geom_line(aes(x=x, y=y, color = fill)) +
  labs( title="Using LONG data frame" , y="Y label" , x="X label" ) +
  geom_text(data = group_by(longDF1, fill) %>% top_n(1, x),
            aes(x = x, y = y, label = toupper(fill), color = fill),
            hjust = 1 , vjust = -0.5, show.legend = FALSE) +
  scale_color_manual(values = c(y1 = "red", y2 = "blue")) +
  scale_fill_manual(values = c(y1 = "pink", y2 = "lightblue"))

这篇关于ggplot2:用图例制作多行+色带的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 04:27