Skip to content

R - 饼图

R - 现代图表:为何要避免饼图以及替代方案

Section titled “R - 现代图表:为何要避免饼图以及替代方案”

饼图是展示“部分与整体”关系的常见方式。然而,在数据可视化领域,它们通常不被推荐。为什么?因为人类不擅长精确比较角度。对我们来说,比较长度要容易得多,这使得条形图成为一种更有效、更真实地显示比例数据的方式。

本教程将首先向您展示使用功能强大的 ggplot2 库创建饼图的现代方法。然后,它将演示为什么简单的条形图通常是更好的替代方案。

忘掉基础 R 的 pie() 函数吧。ggplot2 作为 tidyverse 的基石,提供了一种灵活而强大的图形语法。我们不直接创建饼图;相反,我们先创建一个条形图,然后转换其坐标系。

# Install ggplot2 if you haven't already
# install.packages("tidyverse")
library(ggplot2)
library(dplyr)

ggplot2 最适合使用数据框 (data frame) 或 tibble 格式的数据。

# Create a tibble for our data
city_data <- tibble(
city = c("London", "New York", "Singapore", "Mumbai"),
market_share = c(21, 62, 10, 53)
)

ggplot2 饼图的基础是一个堆积条形图,我们将值映射到 y 美学 (aesthetic)。

bar_plot <- ggplot(city_data, aes(x = "", y = market_share, fill = city)) +
geom_col(width = 1)
# This creates a single stacked bar. Now we transform it.

步骤 3:使用 coord_polar() 转换为饼图

Section titled “步骤 3:使用 coord_polar() 转换为饼图”

神奇之处在于 coord_polar(),它将条形图转换为圆形。

pie_chart <- bar_plot +
coord_polar(theta = "y") +
labs(
title = "Market Share by City",
fill = "City",
x = NULL, # Remove x-axis label
y = NULL # Remove y-axis label
) +
theme_minimal() + # Use a clean theme
theme(axis.text = element_blank(), axis.ticks = element_blank()) # Remove axis text
print(pie_chart)

输出描述: 此代码生成一个简洁、现代的饼图。扇区根据城市着色,并自动生成图例。标题显示在顶部。背景简洁,没有分散注意力的网格线或坐标轴标签。

为饼图添加标签对于可读性至关重要。我们首先使用 dplyr 计算百分比。

# Calculate percentages and label positions
city_data <- city_data %>%
mutate(
percentage = market_share / sum(market_share),
label = scales::percent(percentage)
)
# Rebuild the plot and add a geom_text layer
ggplot(city_data, aes(x = "", y = percentage, fill = city)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
# Add labels inside the slices
geom_text(
aes(label = label),
position = position_stack(vjust = 0.5) # Center the labels
) +
labs(title = "Market Share by City", fill = "City", x = NULL, y = NULL) +
theme_void() # A theme perfect for pie charts

现在,让我们用相同的数据创建一个条形图。请注意,比较纽约 (62) 和孟买 (53) 变得多么容易。在饼图中,这种比较很难。

# Use reorder() to sort the bars for easier comparison
ggplot(city_data, aes(x = reorder(city, -market_share), y = market_share, fill = city)) +
geom_col() +
geom_text(aes(label = market_share), vjust = -0.5) + # Add value labels
labs(
title = "Market Share by City",
x = "City",
y = "Market Share (Units)"
) +
theme_minimal() +
theme(legend.position = "none") # Remove legend as fill is redundant

结论: 尽管您可以在 R 中制作饼图,但您应该始终考虑条形图是否能更有效地传达您的信息。谨慎使用饼图,仅在少量类别且这些类别加起来构成有意义的整体时使用。

在数据科学和统计学中,强烈不推荐使用 3D 饼图。3D 透视会扭曲扇区的大小,使其具有误导性。前景中的扇区看起来比背景中大小相同的扇区更大。因此,ggplot2 不提供内置的 3D 饼图创建方式,以强化现代可视化的最佳实践。始终优先选择 2D 表示。