一、气泡图
气泡图是一种数据可视化工具,它在传统的二维散点图的基础上增加了一个维度,使得我们能够同时观察三个变量之间的关系。这种图表通过点的大小来表示第三个数值变量的大小,从而提供了一种直观的方式来探索数据中的模式和趋势。
在定义气泡图时,我们通常需要以下三个数值变量:
- X轴变量:这个变量的值决定了气泡在水平轴上的位置。它通常代表一个连续的数值,如时间、年龄或某种度量。
- Y轴变量:这个变量的值决定了气泡在垂直轴上的位置。这同样是一个连续的数值,可以是另一个度量或某种性能指标。
- 气泡大小变量:这个变量的值决定了气泡的大小。气泡的大小通常与一个度量的大小成正比,如经济规模、人口数量或其他重要的数值指标。
气泡图的一个经典例子是使用Gapminder数据集。Gapminder是一个非营利组织,由Hans Rosling创立,旨在通过提供易于理解的数据来促进全球发展的教育和理解。Gapminder数据集包含了世界各地区和国家在不同年份的统计数据,包括但不限于平均预期寿命、人均GDP和人口规模。
以下是一个使用Gapminder数据集摘要的例子,该数据集通过Hans Rosling的Ted演讲而闻名。它提供了100多个国家的平均预期寿命、人均GDP和人口规模的数据。该数据集可通过gapminder R包获取。
# Libraries
library(tidyverse) # 加载tidyverse包,提供数据整理和图形制作的工具
library(hrbrthemes) # 加载hrbrthemes包,提供了一些美观的主题
library(viridis) # 加载viridis包,提供了颜色渐变方案
library(gridExtra) # 加载gridExtra包,用于在网格中排列图形
library(ggrepel) # 加载ggrepel包,用于避免点标签重叠
library(plotly) # 加载plotly包,用于创建交互式图形
# The dataset is provided in the gapminder library
library(gapminder) # 加载gapminder包,包含有关不同国家和地区随时间变化的生命期望、GDP和人口的数据
data <- gapminder %>%
filter(year=="2007") %>% # 筛选出2007年的数据
dplyr::select(-year) # 移除年份列
# Show a bubbleplot
data %>%
mutate(pop=pop/1000000) %>% # 将人口数量转换为百万单位
arrange(desc(pop)) %>% # 按人口数量降序排列数据
mutate(country = factor(country, country)) %>% # 将国家名称转换为因子类型,保持原有顺序
ggplot( aes(x=gdpPercap, y=lifeExp, size = pop, color = continent)) + # 创建ggplot对象,设置x轴为人均GDP,y轴为预期寿命,点的大小代表人口,颜色代表大洲
geom_point(alpha=0.7) + # 添加点图层,设置透明度为0.7
scale_size(range = c(1.4, 19), name="Population (M)") + # 设置点的大小范围,并添加大小图例
scale_color_viridis(discrete=TRUE, guide=FALSE) + # 使用viridis颜色方案,并且不显示颜色图例
theme_minimal() + # 应用最小化主题
theme(legend.position="bottom") # 将图例放置在底部
这段代码使用了R语言和多个tidyverse包来创建一个气泡图,展示了2007年不同国家的人均GDP、预期寿命和人口大小。
这段代码最终生成了一个静态的气泡图,其中每个气泡代表一个国家,气泡的位置由人均GDP(x轴)和预期寿命(y轴)决定,气泡的大小表示人口数量(以百万为单位),而气泡的颜色则表示该国家所在的大洲。由于使用了theme(legend.position="bottom")
,图例被放置在图的底部。
在此图表中,人均GDP与预期寿命之间的关系相当明显:富裕国家的居民倾向于更长寿,当人均GDP达到约10,000美元时,存在一个阈值效应。这种关系本可以通过经典的散点图来检测,但气泡大小允许通过第三层信息来细化这一结果:国家人口。
最后一个变量比X轴和Y轴上的变量更难以解读。确实,人类眼睛对面积的解释能力较弱。但信息是存在的,如果人口与人均GDP或预期寿命之间存在明确的关系,我们将会发现它。
二、变体
前面的图表相当有趣,因为它允许我们理解人均GDP与预期寿命之间的关系。然而,不知道图表极端部分的国家,或者不知道哪些国家偏离了总体趋势,可能会让人感到挫败。如同往常,对图表进行注释是使其具有洞察力的关键步骤:
# Prepare data
tmp <- data %>%
mutate(
annotation = case_when(
gdpPercap > 5000 & lifeExp < 60 ~ "yes", # 如果人均GDP大于5000且预期寿命小于60岁,标记为"yes"
lifeExp < 30 ~ "yes", # 如果预期寿命小于30岁,标记为"yes"
gdpPercap > 40000 ~ "yes" # 如果人均GDP大于40000,标记为"yes"
)
) %>%
mutate(pop=pop/1000000) %>% # 将人口数量转换为百万单位
arrange(desc(pop)) %>% # 按人口数量降序排列数据
mutate(country = factor(country, country)) # 将国家名称转换为因子类型,保持原有顺序
# Plot
ggplot( tmp, aes(x=gdpPercap, y=lifeExp, size = pop, color = continent)) + # 创建ggplot对象,设置x轴为人均GDP,y轴为预期寿命,点的大小代表人口,颜色代表大洲
geom_point(alpha=0.7) + # 添加点图层,设置透明度为0.7
scale_size(range = c(1.4, 19), name="Population (M)") + # 设置点的大小范围,并添加大小图例
scale_color_viridis(discrete=TRUE) + # 使用viridis颜色方案
theme_minimal() + # 应用minimal主题
theme(legend.position="none") + # 不显示图例
geom_text_repel(data=tmp %>% filter(annotation=="yes"), aes(label=country), size=4 ) # 对满足条件的国家添加文本标签,使用geom_text_repel避免标签重叠
这段代码使用R语言和tidyverse包来准备数据并创建一个气泡图,图中包含了特定条件下的国家标注。
在这段代码中,首先对数据进行了预处理,创建了一个新的变量annotation
,根据人均GDP和预期寿命的特定条件将国家标记为"yes"。然后,将人口数量转换为百万单位,并按人口数量降序排列数据,同时将国家名称转换为因子类型。
在绘图部分,使用ggplot
函数创建了一个气泡图,其中气泡的大小和颜色分别代表人口数量和大洲。通过geom_point
添加了点图层,并设置了透明度。scale_size
和scale_color_viridis
分别设置了点的大小范围和颜色方案。
最后,使用geom_text_repel
函数为那些满足annotation=="yes"
条件的国家添加了文本标签,geom_text_repel
会自动调整标签位置以避免重叠,size=4
设置了标签的字体大小。
三、交互性
遵循相同的思路,气泡图可能是使用交互性最有意义的图表类型。在下面的图表中,您可以通过悬停气泡来获取国家名称,并放大图表的特定部分。
# Interactive version
p <- data %>%
mutate(gdpPercap=round(gdpPercap,0)) %>% # 将人均GDP四舍五入到最接近的整数
mutate(pop=round(pop/1000000,2)) %>% # 将人口数量转换为百万单位并保留两位小数
mutate(lifeExp=round(lifeExp,1)) %>% # 将预期寿命四舍五入到最接近的十分位
arrange(desc(pop)) %>% # 按人口数量降序排列数据
mutate(country = factor(country, country)) %>% # 将国家名称转换为因子类型,保持原有顺序
mutate(text = paste("Country: ", country, "\nPopulation (M): ", pop, "\nLife Expectancy: ", lifeExp, "\nGdp per capita: ", gdpPercap, sep="")) %>% # 创建一个新变量text,包含国家名称、人口、预期寿命和人均GDP的信息
ggplot( aes(x=gdpPercap, y=lifeExp, size = pop, color = continent, text=text)) + # 创建ggplot对象,设置x轴为人均GDP,y轴为预期寿命,点的大小代表人口,颜色代表大洲,text变量用于交互式提示
geom_point(alpha=0.7) + # 添加点图层,设置透明度为0.7
scale_size(range = c(1.4, 19), name="Population (M)") + # 设置点的大小范围,并添加大小图例
scale_color_viridis(discrete=TRUE, guide=FALSE) + # 使用viridis颜色方案,并且不显示颜色图例
theme_minimal() + # 应用最小化主题
theme(legend.position="none") # 不显示图例
ggplotly(p, tooltip="text") # 将静态图转换为交互式图,并设置鼠标悬停时显示text变量的信息
这段代码使用R语言和tidyverse包以及plotly包来创建一个交互式的气泡图,图中展示了不同国家的人均GDP、预期寿命和人口大小。
在这段代码中,首先对数据进行了预处理,包括四舍五入人均GDP、人口和预期寿命的值,按人口数量降序排列数据,将国家名称转换为因子类型,并创建了一个新的变量text
,该变量包含了用于交互式提示的文本信息。
接着,使用ggplot
函数创建了一个静态的气泡图,其中气泡的大小和颜色分别代表人口数量和大洲。通过geom_point
添加了点图层,并设置了透明度。scale_size
和scale_color_viridis
分别设置了点的大小范围和颜色方案。theme_minimal
应用了一个简洁的主题,而theme(legend.position="none")
则隐藏了图例。
最后,使用ggplotly
函数将静态图转换为交互式图,并通过tooltip="text"
参数设置鼠标悬停时显示text
变量中的信息,这样用户可以查看每个气泡对应的国家详细信息。