最近很多小伙伴私信我棒棒糖图怎么画,其实非常简单,就是简单的点和线连接。
画点就用geom_point()
,画线就用geom_segment()
。当然,如果你对ggplot2
很熟悉,你完全有更多选择,不必拘泥于形式。
下面给大家展示几个例子。
简单使用 首先我们构造一个数据,这个数据共有3列,1列是数值型变量,另外2列是离散型变量。
set.seed(123 ) df <- data.frame( x = LETTERS[1 :7 ], y = sample(10 :20 ,7 ), g = sample(paste0("type" ,1 :3 ),7 ,replace = T ) ) df # 数据就像下面这样 ## x y g ## 1 A 12 type2 ## 2 B 20 type2 ## 3 C 11 type1 ## 4 D 15 type2 ## 5 E 19 type3 ## 6 F 14 type1 ## 7 G 13 type3
这样一个数据已经足够我们画出很好看的棒棒糖图了。在此之前,还是先给大家展示一个简单的版本。
library (ggplot2) p1 <- ggplot(df, aes(x=y,y=x))+ geom_point()+ geom_segment(aes(xend=0 ,yend=x)) p1
plot of chunk unnamed-chunk-2 这就是一个最原始版本的棒棒糖图,基本的元素都有了,剩下的只要更改下大小、颜色、主题就行了。
在ggplot2
中,画一条线段(segment)需要给4个坐标,x, xend, y, yend
,也就是这条线在x轴上的起点和终点以及在y轴上的起点和终点 。理解了这个,棒棒糖图自然就会画了。
美化 颜色映射首先,我们可以给点和线画上不同的颜色,让它们根据g
这一列的不同类型,上不同的颜色。
library (forcats) p2 <- ggplot(df, aes(x=y,y=fct_reorder(x,y), # 让x按照y的大小排序 color=g))+ geom_point(size = 5 )+ geom_segment(aes(xend=0 ,yend=x),size=2 )+ labs(x=NULL ,y=NULL )+ theme_bw() p2
plot of chunk unnamed-chunk-3 双向棒棒糖图很多人可能见过负值和正值方向不同的棒棒糖,也是非常简单,只要你的数据中既有正值也有负值就可以了,代码都不需要变!
set.seed(123 ) df1 <- data.frame( x = LETTERS[1 :20 ], y = sample(-10 :20 ,20 ), # 有正值也有负值 g = sample(paste0("type" ,1 :3 ),20 ,replace = T ), s = sample(1 :10 ,20 ,replace = T ) ) df1## x y g s ## 1 A 20 type2 6 ## 2 B 4 type3 9 ## 3 C 8 type2 2 ## 4 D 3 type1 5 ## 5 E -8 type3 8 ## 6 F -1 type3 2 ## 7 G 7 type1 1 ## 8 H 11 type3 9 ## 9 I 0 type2 9 ## 10 J -6 type1 6 ## 11 K 9 type3 5 ## 12 L 17 type1 9 ## 13 M 13 type1 10 ## 14 N -2 type2 4 ## 15 O 16 type3 6 ## 16 P -3 type3 8 ## 17 Q 15 type1 6 ## 18 R -4 type3 6 ## 19 S 19 type1 7 ## 20 T 14 type3 1
这时候再画图,自动就会变成双向的,而且,在上面的数据中,我们增加了一列数值型变量s
,把这个s
映射给点,就会形成不同的点的大小。
p3 <- ggplot(df1, aes(x=y,y=fct_reorder(x,y),color=g))+ geom_point(aes(size = s))+ # 改变点的大小 geom_segment(aes(xend=0 ,yend=x),size=2 )+ labs(x=NULL ,y=NULL )+ theme_bw() p3
plot of chunk unnamed-chunk-5 很多人可能更喜欢线的颜色统一点,点的颜色可以不同,这也很简单,只要把映射颜色的变量放在单独的geom
中就可以了。
library (forcats) p4 <- ggplot(df1,aes(x=y,y= fct_reorder(x,y)))+ geom_point(aes(size = s ,color=g))+ # 单独映射 geom_segment(aes(xend=0 ,yend=x),size=1.2 ,alpha=0.6 ,color="grey50" ,linetype=3 )+ # 线的颜色、形状、透明度都能自定义 labs(x=NULL ,y=NULL )+ theme_bw() p4
plot of chunk unnamed-chunk-6 横向棒棒糖图如果你更喜欢横向的棒棒糖,非常简单,只要交换一下x轴和y轴就可以了,不过这时xend和yend也要跟着变一下!
p5 <- ggplot(df1, aes(x = fct_reorder(x,y), y = y, color = g))+ geom_point(aes(size = s))+ geom_segment(aes(xend = x,yend = 0 ))+ labs(x=NULL ,y=NULL )+ theme_bw() p5
plot of chunk unnamed-chunk-7 正负值不同颜色还有小伙伴可能想要不同朝向的不同颜色,朝上的一个颜色,朝下的一个颜色。也很简单,只要你根据自己的值是正是负,再新增1列新的变量就可以了。
library (dplyr)## ## 载入程辑包:'dplyr' ## The following objects are masked from 'package:stats': ## ## filter, lag ## The following objects are masked from 'package:base': ## ## intersect, setdiff, setequal, union # 新建1列,如果是正值,就显示 positive,负值就显示negtive df2 <- df1 %>% mutate(f = case_when(y < 0 ~ "negtive" , y >= 0 ~ "positive" )) df2## x y g s f ## 1 A 20 type2 6 positive ## 2 B 4 type3 9 positive ## 3 C 8 type2 2 positive ## 4 D 3 type1 5 positive ## 5 E -8 type3 8 negtive ## 6 F -1 type3 2 negtive ## 7 G 7 type1 1 positive ## 8 H 11 type3 9 positive ## 9 I 0 type2 9 positive ## 10 J -6 type1 6 negtive ## 11 K 9 type3 5 positive ## 12 L 17 type1 9 positive ## 13 M 13 type1 10 positive ## 14 N -2 type2 4 negtive ## 15 O 16 type3 6 positive ## 16 P -3 type3 8 negtive ## 17 Q 15 type1 6 positive ## 18 R -4 type3 6 negtive ## 19 S 19 type1 7 positive ## 20 T 14 type3 1 positive
p6 <- ggplot(df2, aes(x = fct_reorder(x,y), y = y))+ geom_segment(aes(xend = x,yend = 0 ),color="grey70" ,size=1.2 )+ #调换这句和下一句代码的顺序会发生什么? geom_point(aes(size = s, color = f))+ # 使用新建的f这一列映射 scale_size_continuous(range = c(3 ,8 ))+ # 点的大小随意更改 labs(x=NULL ,y=NULL )+ theme_bw() p6
plot of chunk unnamed-chunk-9 最后来个全家福:
library (patchwork) p1+p2+p3+p4+p5+p6+plot_layout(ncol=3 )
000016 你可能还需要杠铃图、森林图,请点以下链接:
R语言画dumbbell chart
使用R语言画森林图和误差线(合辑)