一、描述变量分类的可视化图形
在很多情形下,我们对一组数字的大小感兴趣。例如,我们可能想要可视化不同品牌汽车的总销量,或者居住在不同城市的总人数,或者参加不同运动的奥运选手的年龄。在所有这些情形下,都有一组类别(例如,汽车、城市或运动的品牌)和每个类别的值。此示例中的标准可视化是条形图,它有多种变体,包括简单条形以及分组和堆叠条形。条形图进一步演化的替代图形是点图和热图。
(一)条形图/柱形图
为了更好地理解条形图的意义,我们使用一组数据来描述。示例数据来源于国家统计局发布的 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("")