在数据科学领域,数据可视化是展示分析结果的重要桥梁。不知道是什么原因,很多专业的学生喜欢使用Origin进行绘图,考虑到很多时候学校并不承担软件费用,使用盗版软件绘图还可能存在不小心安装到错误的软件进而导致数据泄露的风险。
虽然说Origin学习门槛较低,也能满足最基本的绘图需要,但随着目前数据分析越来越复杂,并且几乎所有学科都有与人工智能交叉发展的趋势。对有志于绘制出更丰富结果的同学来说,我认为R 的 ggplot2 和 Python 的 Seaborn/Matplotlib 是两大值得学习的可视化工具。不管你使用R还是Python,你可以使绘图工作与统计工作在同一个软件中实现。它们各有千秋,但具体使用中到底哪一个更适合你的需求。
今天我计划通过同一个数据集的三个案例,深入对比了它们在 学习难度、代码理解难度、代码复杂程度 和 美学优化能力 四个方面的表现。下面是我的一些个人感受,供大家参考。
1. 学习难度
ggplot2 的逻辑更接近“搭积木”,即通过分层构建(layers)逐步完成图形,非常适合具有统计背景的人。但它要求用户理解 R 的管道数据流(如 dplyr
)和分组操作,这对初学者可能有些陡峭。
Seaborn 在简单场景下非常直观,常见图形一行代码即可生成,但一旦需要高级定制,则要依赖 Matplotlib 的底层语法,复杂度会陡增。
2. 代码理解难度
ggplot2 的代码结构清晰,基于 aes
(美学映射)和图层逻辑展开,语法具有较高一致性,因此更容易理解。
Seaborn/Matplotlib 的逻辑不如 ggplot2 统一,尤其当两者组合使用时,代码的阅读和理解需要花更多时间。
3. 美学优化能力
ggplot2 的默认样式已接近出版级别,主题设置简单直接,一行代码即可切换整体风格。
Seaborn 提供了不错的默认样式,但精细化调整时需要借助 Matplotlib。
科研在某种程度上也是一种重复性的任务,如果需要不断纠正错误,优化图形,那么ggplot2 优势明显,生成精美图形所需代码更少。相比之下,Seaborn 的灵活性虽然是亮点,但代码量会有所增加,尤其在进行个性化调整时。但不论如何,二者都极大减少了将数据从Excel到Origin不同软件间切换的复杂程度,尤其是一旦数据有更新,可以避免版本管理和多次导出导致的手动命名的烦恼。非常适合重复性的绘图工作。而且一段成功的代码还可以全实验室通用,其实最终可以大大降低整个团队的学习难度。
案例实战:三个经典可视化场景
为了更直观地展示差异,我选取了 分组柱状图、PCA 可视化 和 热图 三个常见场景,通过 Iris 数据集分别用 ggplot2 和 Seaborn/Matplotlib 实现,并做了详细美学优化。
案例 1:分组柱状图
ggplot2(R)实现
library(ggplot2)
library(dplyr)
# 数据准备
iris_grouped <- iris %>%
group_by(Species) %>%
summarize(mean_sepal_length = mean(Sepal.Length))
# 绘图
ggplot(iris_grouped, aes(x = Species, y = mean_sepal_length, fill = Species)) +
geom_bar(stat = "identity", color = "black", width = 0.6) +
scale_fill_manual(values = c("Setosa" = "#FF5733", "Versicolor" = "#33FF57", "Virginica" = "#3357FF")) +
labs(
title = "Average Sepal Length by Species",
x = "Species",
y = "Mean Sepal Length",
fill = "Flower Species"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
legend.position = "top"
)
Seaborn/Matplotlib(Python)实现
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 数据准备
iris = sns.load_dataset("iris")
iris_grouped = iris.groupby("species", as_index=False)["sepal_length"].mean()
# 绘图
plt.figure(figsize=(8, 5))
sns.barplot(data=iris_grouped, x="species", y="sepal_length", palette=["#FF5733", "#33FF57", "#3357FF"])
plt.title("Average Sepal Length by Species", fontsize=16, weight='bold')
plt.xlabel("Species", fontsize=12)
plt.ylabel("Mean Sepal Length", fontsize=12)
plt.legend(title="Flower Species", loc="upper center", bbox_to_anchor=(0.5, 1.1), ncol=3)
sns.despine()
plt.tight_layout()
plt.show()
案例 2:PCA 可视化
ggplot2(R)实现
library(ggplot2)
library(FactoMineR)
library(factoextra)
# PCA 计算
pca_res <- PCA(iris[, 1:4], graph = FALSE)
pca_data <- as.data.frame(pca_res$ind$coord)
pca_data$Species <- iris$Species
# 绘图
fviz_pca_ind(pca_res,
geom.ind = "point",
col.ind = iris$Species,
palette = c("#FF5733", "#33FF57", "#3357FF"),
addEllipses = TRUE,
ellipse.level = 0.95,
legend.title = "Species") +
labs(
title = "PCA Plot of Iris Dataset with Confidence Ellipses",
x = "PC1",
y = "PC2"
) +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(hjust = 0.5, face = "bold"))
Seaborn/Matplotlib(Python)实现
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# 数据准备
features = ["sepal_length", "sepal_width", "petal_length", "petal_width"]
x = iris[features]
y = iris["species"]
# PCA 计算
scaler = StandardScaler()
x_scaled = scaler.fit_transform(x)
pca = PCA(n_components=2)
pca_result = pca.fit_transform(x_scaled)
iris_pca = pd.DataFrame(pca_result, columns=["PC1", "PC2"])
iris_pca["species"] = y
# 绘图
plt.figure(figsize=(8, 5))
sns.scatterplot(data=iris_pca, x="PC1", y="PC2", hue="species", palette=["#FF5733", "#33FF57", "#3357FF"], s=80, alpha=0.7)
plt.title("PCA Plot of Iris Dataset", fontsize=16, weight='bold')
plt.xlabel("PC1", fontsize=12)
plt.ylabel("PC2", fontsize=12)
plt.legend(title="Species", loc="best", fontsize=10)
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()
案例 3:热图
ggplot2(R)实现
library(ggplot2)
library(reshape2)
# 数据准备
data(mtcars)
cor_matrix <- cor(mtcars)
cor_melt <- melt(cor_matrix)
# 绘图
ggplot(cor_melt, aes(x = Var1, y = Var2, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "#4575B4", high = "#D73027", mid = "#F7F7F7", midpoint = 0) +
labs(
title = "Correlation Matrix of mtcars Dataset",
x = "",
y = "",
fill = "Correlation"
) +
theme_minimal(base_size = 14) +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(hjust = 0.5, face = "bold")
)
Seaborn/Matplotlib(Python)实现
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.api import datasets
# 导入 mtcars 数据集
mtcars = datasets.get_rdataset("mtcars", "datasets").data
# 查看数据基本信息
print(mtcars.info())
print(mtcars.head())
# 计算相关性矩阵
cor_matrix = mtcars.corr()
# 绘制热图
plt.figure(figsize=(10, 8))
sns.heatmap(cor_matrix,
annot=True,
fmt=".2f",
cmap="coolwarm", # 柔和的颜色映射
vmin=-1, vmax=1, # 限制相关系数范围
linewidths=0.5, # 方块间隔线宽
cbar_kws={'shrink': 0.8}) # 缩小颜色条
plt.title("Correlation Matrix of mtcars Dataset", fontsize=16, weight='bold')
plt.xticks(fontsize=10, rotation=45) # X轴标签旋转
plt.yticks(fontsize=10)
plt.tight_layout()
plt.show()