一、描述变量分类的可视化图形

在很多情形下,我们对一组数字的大小感兴趣。例如,我们可能想要可视化不同品牌汽车的总销量,或者居住在不同城市的总人数,或者参加不同运动的奥运选手的年龄。在所有这些情形下,都有一组类别(例如,汽车、城市或运动的品牌)和每个类别的值。此示例中的标准可视化是条形图,它有多种变体,包括简单条形以及分组和堆叠条形。条形图进一步演化的替代图形是点图和热图。
(一)条形图/柱形图 为了更好地理解条形图的意义,我们使用一组数据来描述。示例数据来源于国家统计局发布的 2021 年国民经济和社会发展统计公报中全国居民人均消费支出数据,如表 6-2-1 所示。 表 6-2-1 2021 年城镇居民消费支出
这种数据通常用条形图来可视化。我们绘制一个从零开始一直延伸到数值最大的条形图(见图 6-2-1~图 6-2-9)。这种可视化图称为柱形图或条形图。柱形图或条形图是最基础,也是最简单的可视化图形,一般用于分类数据频数大小的统计。 在 R 软件中,函数 ggplot2 是最常用的绘图工具库。相关的参数功能描述如下: ● 初始化一个 ggplot 对象,不指定作图内容(内容由 geom_xx 来指定)。 ● 几何对象 geom_xx:表示图形中我们实际看到的图形元素,如点、线等。如绘图时+geom_bar()表示图形中加条形图;+geom_poin()表示生成点;+geom_abline()表示图形中加线条。 ● 函数 theme()允许自定义图表外观。ggplot2 中控制 3 种主要类型的组件。 Axis:控制标题、标签、线条和刻度; 背景:控制背景颜色及主要和次要网格线; 图例:控制位置、文本、符号等。 ● 标度(scale):表示将数据映射到图形空间,比如用颜色、形状来表示不同的数据,通过自定义标度,可以更精确地控制图形的外观。如 scale 中,xlab()控制 x 轴标签;ylab()控制 y 轴标签;ggtitle()控制图形标题。 ● 坐标系(coord):描述了数据如何映射到图形所在的平面,最常用的是直角坐标系。 但坐标系也可以进行转化,以满足不同的需求,如对数坐标、极坐标和地图投影。如 coord_flip()能对坐标轴翻转。 ● 图层(layer):每个图层上都有各种图形元素,最后叠加到一块,形成最终图形的效果。正因为图层,ggplot2 允许用户一步步地构建图形,也方便用户对图层进行修改、增加统 计量或改动数据。 ● 分面(facet):就是控制分组绘图的方法和排列方式。通过坐标系和分面,我们可以 控制图形元素的位置。
# 本例需加载的 R 软件包 library(ggplot2) library(dplyr) library(forcats) library(patchwork) library(hrbrthemes) # 导入或输入示例数据 data <- read.csv("2021 GDP.csv") # 默认柱形图 pp1= data %>% mutate(index = fct_reorder(index, Value)) %>% # 设置顺序 ggplot( aes(x=index, y=Value)) + geom_bar(stat="identity") + theme_bw() pp1 图 6-2-1 柱形图
# 默认条形图 pp2= data %>% mutate(index = fct_reorder(index, Value)) %>% ggplot( aes(x=index, y=Value)) + geom_bar(stat="identity") + theme_bw()+ coord_flip() # 水平条形图 pp2 图 6-2-2 条形图
# 导入或输入示例数据 data1 <- read.csv("流量来源.csv") # 默认显示图例 p1= ggplot(data1, aes(x = 流量来源, fill = 流量来源)) + geom_bar()+ ggtitle("p1")+ # 图形标题 theme_bw() p1 图 6-2-3 默认柱形图
p3= ggplot(data1, aes(x=流量来源, fill=流量来源 )) + geom_bar( ) + scale_fill_brewer(palette = "Set1") + theme_bw()+ theme(legend.position="none")+ ggtitle("p3") p3 图 6-2-4 不显示图例的柱形图
p4= ggplot(data1, aes(x=流量来源, fill=流量来源 )) + geom_bar() + scale_fill_grey(start = 0.25, end = 0.75) + theme_bw()+ theme(legend.position="none")+ ggtitle("p4") p4 图 6-2-5 同色系柱形图
p5= ggplot(data1, aes(x=流量来源, fill=流量来源 )) + geom_bar( ) + scale_fill_manual(values = c("#FF0000", "#008000", #0000FF","#FFFF00","#800080") ) theme_bw()+ theme(legend.position="none")+ ggtitle("p5") p5 图 6-2-6 自定义颜色柱形图
# 数据输入 data <- data.frame( group=c("A ","B ","C ","D ") , value=c(33,62,56,67) , number=c(100,500,459,342) ) #条形宽度设置 data$right <- cumsum(data$number) + 30*c(0:(nrow(data)-1)) data$left <- data$right - data$number # 绘图 ggplot(data, aes(ymin = 0)) + geom_rect(aes(xmin = left, xmax = right, ymax = value, colour = group, fill = group)) + xlab("number") + ylab("value") + theme_bw()+ theme(legend.position="none") 图 6-2-7 不同条形宽度的柱形图
gg1= data2 %>% arrange(val) %>% # 按 val 排序 mutate(name=factor(name, levels=name)) %>% ggplot(aes(x=name, y=val)) + geom_segment( aes(xend=name, yend=0)) + geom_point( size=4, color="orange") + coord_flip() + theme_bw() + xlab("") gg1 图 6-2-8 水平棒棒糖图
gg2= data2 %>% arrange(name) %>% mutate(name = factor(name, levels=c("north", "north-east", "east", "south-east", "south", "south-west", "west", "north-west"))) %>% ggplot( aes(x=name, y=val)) + geom_segment( aes(xend=name, yend=0)) + geom_point( size=4, color="orange") + theme_bw() + xlab("") gg2 图 6-2-9 柱形棒棒糖图
(二)使用 barplot()绘制条形图 barplot 函数可实现在 R 中构建条形图及自定义图表颜色、条形宽度、方向,如图 6-2-10~图 6-2-17 所示。 # 输入数据 data1 <- data.frame( name=letters[1:5], value=sample(seq(4,15),5) ) # 同色条形图 barplot(height=data1$value, names=data1$name, col=rgb(0.2,0.4,0.6,0.6) ) 图 6-2-10 barplot 默认条形图
# 条形颜色不同 library(RColorBrewer) coul <- brewer.pal(5, "Set2") #Set2 是函数自动的颜色库 barplot(height=data1$value, names=data1$name, col=coul ) 图 6-2-11 设置系统颜色的柱形图
# 空心条形图 barplot(height=data1$value, names=data1$name, border="#69b3a2", col="white" ) 图 6-2-12 空心柱形图
# 使用 xlab、ylab 和 main 进行自定义 y 轴值 barplot(height=data1$value, names=data1$name, col=rgb(0.8,0.1,0.1,0.6), xlab="categories", ylab="values", main="My title", ylim=c(0,40) ) 图 6-2-13 自定义 y 值的柱形图
#水平条形图 barplot(height=data1$value, names=data1$name, col="#69b3a2", horiz=T, las=1 ) 图 6-2-14 水平条形图
# 空间位置不同的条形 barplot(height=data1$value, names=data1$name, col=rgb(0.2,0.4,0.6,0.6), space=c(0.1,0.2,3,1.5,0.3) ) 图 6-2-15 条形空间不同的柱形图
# 条形宽度不同的条形图 barplot(height=data1$value, names=data1$name, col=rgb(0.2,0.4,0.6,0.6), width=c(0.1,0.2,3,1.5,0.3) ) 图 6-2-16 条形宽度不同的柱形图
# 条纹填充的条形图 barplot( height=data1$value, names=data1$name , density=c(5,10,20,30,7) , angle=c(0,45,90,11,36) , col="brown" ) 图 6-2-17 条纹填充的柱形图
(三)分组和堆叠条形图/柱形图 前面所有示例都使用条形图展示了一个分类变量的变化。然而,我们经常同时对两个及多个分类变量感兴趣,因此,在单变量分组的基础上,学习多变量分组条形图,能够在不同维度上展示数据。具体方法是在 x 轴的每个位置绘制一组条形,由一个分类变量确定,然后根据另一个分类变量在每个组内绘制条形。 以下示例主要展示了分组数据可视化方法。 library(ggplot2) # 输入一个模拟数据 specie <- c(rep("sorgho" , 3) , rep("poacee" , 3) , rep("banana" , 3) , rep("triticum" , 3) ) condition <- rep(c("normal" , "stress" , "Nitrogen") , 4) value <- abs(rnorm(12 , 0 , 15)) data <- data.frame(specie,condition,value) 模拟输入的数据集必须有 3 个列,包括数值(value)以及组(spec)和子组(condition) 2 个分类变量,如图 6-2-18 所示。 # 绘图 ggplot(data, aes(fill=condition, y=value, x=specie)) + geom_bar(position="dodge", stat="identity")+ theme_bw() 图 6-2-18 分组柱形图/条形图
● aes()参数设置中,fill 是子组(condition),x 是组(spec),y 是值(value)。 ● 在 geom_bar()参数中,position=“dodge”必须设置,以使条形图彼此相邻。 堆叠的柱形图或条形图与上面的分组条形图、柱形图非常相似。子组只是显示在彼此的顶部,而不是旁边,如图 6-2-19 所示。绘制这个图,唯一需要改变的是将 position 参数修改为“stack”。 图 6-2-19 堆叠柱形图/条形图
# position 中参数"dodge" 切换为 “stack” ggplot(data, aes(fill=condition, y=value, x=specie)) + geom_bar(position="stack", stat="identity")+ theme_bw() 同样,切换到百分比堆叠 barplot 也简单,只需将 position 的参数改为“fill”。现在,每个子群体的百分比被表示出来,允许研究它们在整体中比例的变化,如图 6-2-20 所示。 # 绘图 ggplot(data, aes(fill=condition, y=value, x=specie)) + geom_bar(position="fill", stat="identity") 图 6-2-20 百分比堆叠柱形图/条形图
通常情况下,还需要对图做一些必要的修改,以使图表看起来更好和个性化,如图 6-2-21 所示。例如: ● 添加标题 title; ● 自定义图表格式 theme; ● 自定义图形颜色; ● 自定义轴 # library library(ggplot2) library(viridis) library(hrbrthemes) library(gcookbook) # 绘图 ggplot(data, aes(fill=condition, y=value, x=specie)) + geom_bar(position="stack", stat="identity") + scale_fill_viridis(discrete = T) + ggtitle("Studying 4 species") + theme_ipsum(base_family = "") + xlab("") 图 6-2-21 堆叠条形图/柱形图
此外,使用 facet_wrap()功能,可以多图显示分组数据比较的意义,如图 6-2-22 所示。 # 绘图 ggplot(data, aes(fill=condition, y=value, x=condition)) + geom_bar(position="dodge", stat="identity") + 图 6-2-22 分组显示的条形图/柱形图
scale_fill_viridis(discrete = T, option = "E") + ggtitle("Studying 4 species..") + facet_wrap(~specie) + theme_ipsum(base_family = "") + theme(legend.position="none") + xlab("")