Bohrium
robot
新建

空间站广场

论文
Notebooks
比赛
课程
Apps
我的主页
我的Notebooks
我的论文库
我的足迹

我的工作空间

任务
节点
文件
数据集
镜像
项目
数据库
公开
快速开始 seaborn|入门 seaborn 数据可视化
Tutorial
Seaborn
Data Visualize
TutorialSeabornData Visualize
MileAway
发布于 2023-06-09
推荐镜像 :Basic Image:bohrium-notebook:2023-04-07
推荐机型 :c2_m4_cpu
赞 6
10
快速开始 seaborn|入门 seaborn 数据可视化
目标
目录
背景
实践
1 认识 seaborn
1.1 什么是 seaborn
1.2 安装 seaborn
1.3 验证 seaborn 安装并查看版本
2 seaborn 方法
2.1 快速入门示例
2.2 用于统计图像
2.2.1 统计估计
2.2.2 分布表示
2.2.3 分类数据的图表
2.3 复杂数据集的多元视图
2.3.1 用于构建图形的低级工具
2.4 默认风格和灵活的定制
3 与 matplotlib 的关系
总结
进一步阅读
参考

快速开始 seaborn|入门 seaborn 数据可视化

代码
文本

Open In Bohrium

代码
文本

©️ Copyright 2023 @ Authors
作者:阙浩辉 📨
日期:2023-05-09
共享协议:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

代码
文本

🎯 本教程旨在快速掌握使用 Seaborn 进行数据可视化的范式周期。

  • 一键运行,你可以快速在实践中检验你的想法。

  • 丰富完善的注释,对于入门者友好。

代码
文本

Bohrium Notebook 界面,你可以点击界面上方蓝色按钮 开始连接,选择 bohrium-notebook 镜像及任何一款节点配置,稍等片刻即可运行。

代码
文本

目标

入门 seaborn 进行数据可视化。

在学习本教程后,你将能够:

  • 绘制统计估计、分布表示、分类数据的图表
  • 使用 seaborn 对复杂数据集进行多元视图绘制
  • 使用 seaborn 默认的绘图主题以及自定义你的主题

阅读该教程【最多】约需 15 分钟,让我们开始吧!

代码
文本

背景

这是对 seaborn 的简短介绍,主要面向新用户。seaborn 是一个用于在 Python 中制作统计图形的库。它建立在 matplotlib 之上,并与 Pandas数据结构紧密集成。

你需要提前掌握以下知识:

  • 非常基本的 Python 知识
代码
文本

实践

代码
文本

1 认识 seaborn

在这一部分,你会了解什么是 seaborn,在 Bohrium 中使用 seaborn,验证安装并查看版本。

代码
文本

1.1 什么是 seaborn

seaborn 是基于 Python 且非常受欢迎的图形可视化库,在 Matplotlib 的基础上,进行了更高级的封装,使得作图更加方便快捷。即便是没有什么基础的人,也能通过极简的代码,做出具有分析价值而又十分美观的图形。

seaborn 可以实现 Python 环境下的绝大部分探索性分析的任务,图形化的表达帮助你对数据进行分析,而且对 Python 的其他库(比如 Numpy/Pandas/Scipy)有很好的支持。

seaborn 官方文档对其能够绘制的各类图像进行了展示。

seaborn

代码
文本

1.2 安装 seaborn

本教程是一个 Bohrium Notebook。Python 程序可直接在浏览器中运行,Bohrium 已安装 seaborn

要按照本教程进行操作,请点击本页顶部的按钮,在 Bohrium Notebook 中运行本笔记本。

  1. 你可以点击界面上方蓝色按钮 开始连接,选择 bohrium-notebook 镜像及任何一款计算机型,稍等片刻即可运行。

  2. 若要运行笔记本中的所有代码,请点击左上角“ 运行全部单元格 ”。若要一次运行一个代码单元,请选择需要运行的单元格,然后点击左上角 “运行选中的单元格” 图标。

如果你的 Bohrium 镜像尚未安装 seaborn, 最方便的方法是通过 pip 安装:

代码
文本
[1]
! pip install seaborn

# # seaborn 需要调用 urlopen,在本镜像中需要修改一下 Proxy,您无需了解这方面的内容
# from urllib.request import urlopen, ProxyHandler, build_opener

# proxy = ProxyHandler({'http': 'http://ga.dp.tech:8118',
# 'https': 'http://ga.dp.tech:8118'})
# opener = build_opener(proxy)
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: seaborn in /opt/conda/lib/python3.8/site-packages (0.11.2)
Requirement already satisfied: scipy>=1.0 in /opt/conda/lib/python3.8/site-packages (from seaborn) (1.7.3)
Requirement already satisfied: pandas>=0.23 in /opt/conda/lib/python3.8/site-packages (from seaborn) (1.5.3)
Requirement already satisfied: numpy>=1.15 in /opt/conda/lib/python3.8/site-packages (from seaborn) (1.22.4)
Requirement already satisfied: matplotlib>=2.2 in /opt/conda/lib/python3.8/site-packages (from seaborn) (3.7.1)
Requirement already satisfied: packaging>=20.0 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (23.0)
Requirement already satisfied: pyparsing>=2.3.1 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (3.0.9)
Requirement already satisfied: contourpy>=1.0.1 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (1.0.5)
Requirement already satisfied: kiwisolver>=1.0.1 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (1.4.4)
Requirement already satisfied: python-dateutil>=2.7 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (2.8.2)
Requirement already satisfied: importlib-resources>=3.2.0 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (5.2.0)
Requirement already satisfied: fonttools>=4.22.0 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (4.38.0)
Requirement already satisfied: cycler>=0.10 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (0.11.0)
Requirement already satisfied: pillow>=6.2.0 in /opt/conda/lib/python3.8/site-packages (from matplotlib>=2.2->seaborn) (9.4.0)
Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.8/site-packages (from pandas>=0.23->seaborn) (2022.7)
Requirement already satisfied: zipp>=3.1.0 in /opt/conda/lib/python3.8/site-packages (from importlib-resources>=3.2.0->matplotlib>=2.2->seaborn) (3.14.0)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.8/site-packages (from python-dateutil>=2.7->matplotlib>=2.2->seaborn) (1.16.0)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
代码
文本

如果你需要使用更特定于你的平台或包管理器的安装方法,你可以在这里查看更完整的安装说明。

代码
文本

1.3 验证 seaborn 安装并查看版本

安装 seaborn 后,确认库已成功安装并且你可以开始使用它。

不要跳过此步骤。

如果 seaborn 未正确安装或在此步骤中引发错误,则将无法运行之后的示例。

代码
文本
[2]
import seaborn as sns
print(sns.__version__) # sns.__version__ 返回安装的 seaborn 的版本号
0.11.2
代码
文本

2 seaborn 方法

在这一节中,你会了解到一些 seaborn 的基础方法,包括:

  • 一个快速入门示例
  • 统计数据可视化
  • 复杂数据的多元视图
  • 默认风格与风格切换
代码
文本

2.1 快速入门示例

代码
文本

seaborn 是我们在这个简单示例中唯一需要导入的库。为了方便使用,使用 sns 作为缩写。

代码
文本
[3]
# 导入 seaborn
import seaborn as sns

# 导入其它工具
import pandas as pd
import os
import matplotlib.pyplot as plt
代码
文本

在幕后,seaborn 使用 matplotlib 来绘制其情节。对于交互式工作,建议在 matplotlib 模式下使用 Jupyter/IPython 界面,否则当您想查看绘图时,您必须调用 matplotlib.pyplot.show()

代码
文本
[4]
# Apply the default theme
sns.set_theme()
代码
文本

这一步 matplotlib rcParam 系统,并且会影响所有 matplotlib 绘图的外观,即使您不使用 seaborn 制作它们。除了默认主题之外,还有其他几个选项,您可以独立地控制图的样式和缩放,以便在演示文稿上下文中快速转换您的工作(例如,制作一个版本的图,当在演讲期间投影时,字体可读)。如果您喜欢 matplotlib 默认设置或喜欢其他主题,则可以跳过此步骤并仍然使用 seaborn 绘图函数。

代码
文本
[5]
# Load an example dataset

# 以下两个操作是等效的
# tips = sns.load_dataset("tips")
! wget https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv
tips = pd.read_csv('tips.csv')
os.remove('tips.csv')
tips
--2023-03-27 21:46:35--  https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv
Resolving ga.dp.tech (ga.dp.tech)... 10.255.255.41
Connecting to ga.dp.tech (ga.dp.tech)|10.255.255.41|:8118... connected.
Proxy request sent, awaiting response... 200 OK
Length: 9729 (9.5K) [text/plain]
Saving to: ‘tips.csv’

tips.csv            100%[===================>]   9.50K  --.-KB/s    in 0.04s   

2023-03-27 21:46:35 (258 KB/s) - ‘tips.csv’ saved [9729/9729]

total_bill tip sex smoker day time size
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
2 21.01 3.50 Male No Sun Dinner 3
3 23.68 3.31 Male No Sun Dinner 2
4 24.59 3.61 Female No Sun Dinner 4
... ... ... ... ... ... ... ...
239 29.03 5.92 Male No Sat Dinner 3
240 27.18 2.00 Female Yes Sat Dinner 2
241 22.67 2.00 Male Yes Sat Dinner 2
242 17.82 1.75 Male No Sat Dinner 2
243 18.78 3.00 Female No Thur Dinner 2

244 rows × 7 columns

代码
文本

大多数文档中的代码将使用load_dataset()函数快速访问示例数据集。这些数据集没有什么特别之处:它们只是pandas dataframe,我们可以使用pandas.read_csv()加载它们或手动构建它们。文档中的大多数示例将使用pandas dataframe指定数据,但是seaborn对其接受的数据结构非常灵活。

代码
文本
[6]
# Create a visualization
sns.relplot(
data=tips,
x="total_bill", y="tip", col="time",
hue="smoker", style="smoker", size="size",
)
plt.show()
代码
文本

这个图显示了使用单个调用seaborn函数relplot()在”tips“数据集中的五个变量之间的关系。请注意,我们仅提供了变量的名称和它们在图中的作用。与直接使用matplotlib时不同,不需要使用颜色值或标记代码来指定图形元素的属性。在幕后,seaborn处理了从数据框中的值到matplotlib理解的参数的转换。这种声明性方法使您可以专注于要回答的问题,而不是控制matplotlib的细节。

代码
文本

2.2 用于统计图像

没有普遍最佳的数据可视化方式。不同的问题最好由不同的图表来回答。seaborn通过使用一致的面向数据集的API轻松切换不同的可视化表示方式。

代码
文本

函数relplot()的名称是这样命名的,因为它旨在可视化许多不同的统计关系。虽然散点图通常很有效,但其中一个变量表示时间度量的关系更适合用线表示。relplot()函数具有方便的kind参数,可让您轻松切换到此备用表示方式:

代码
文本
[7]
# 以下两个操作是等效的
# dots = sns.load_dataset("dots")
! wget https://raw.githubusercontent.com/mwaskom/seaborn-data/master/dots.csv
dots = pd.read_csv('dots.csv')
os.remove('dots.csv')
dots
--2023-03-27 21:46:38--  https://raw.githubusercontent.com/mwaskom/seaborn-data/master/dots.csv
Resolving ga.dp.tech (ga.dp.tech)... 10.255.255.41
Connecting to ga.dp.tech (ga.dp.tech)|10.255.255.41|:8118... connected.
Proxy request sent, awaiting response... 200 OK
Length: 25742 (25K) [text/plain]
Saving to: ‘dots.csv’

dots.csv            100%[===================>]  25.14K  --.-KB/s    in 0.04s   

2023-03-27 21:46:38 (660 KB/s) - ‘dots.csv’ saved [25742/25742]

align choice time coherence firing_rate
0 dots T1 -80 0.0 33.189967
1 dots T1 -80 3.2 31.691726
2 dots T1 -80 6.4 34.279840
3 dots T1 -80 12.8 32.631874
4 dots T1 -80 25.6 35.060487
... ... ... ... ... ...
843 sacc T2 300 3.2 33.281734
844 sacc T2 300 6.4 27.583979
845 sacc T2 300 12.8 28.511530
846 sacc T2 300 25.6 27.009804
847 sacc T2 300 51.2 30.959302

848 rows × 5 columns

代码
文本
[8]
sns.relplot(
data=dots, kind="line",
x="time", y="firing_rate", col="align",
hue="choice", size="coherence", style="choice",
facet_kws=dict(sharex=False),
)
plt.show()
代码
文本

请注意,size和style参数在散点图和线图中都有使用,但它们会以不同的方式影响两个可视化效果:在散点图中更改标记区域和符号,而在线图中更改线宽和虚线。我们不需要记住这些细节,让我们专注于图的总体结构和我们想要传达的信息。

代码
文本
2.2.1 统计估计

通常,我们对其他变量的平均值感兴趣。许多seaborn函数将自动执行必要的统计估计,以回答这些问题:

代码
文本
[9]
import pandas as pd
import os

# 以下两个操作是等效的
# fmri = sns.load_dataset("fmri")
! wget https://raw.githubusercontent.com/mwaskom/seaborn-data/master/fmri.csv
fmri = pd.read_csv('fmri.csv')
os.remove('fmri.csv')
fmri
--2023-03-27 21:46:40--  https://raw.githubusercontent.com/mwaskom/seaborn-data/master/fmri.csv
Resolving ga.dp.tech (ga.dp.tech)... 10.255.255.41
Connecting to ga.dp.tech (ga.dp.tech)|10.255.255.41|:8118... connected.
Proxy request sent, awaiting response... 200 OK
Length: 38329 (37K) [text/plain]
Saving to: ‘fmri.csv’

fmri.csv            100%[===================>]  37.43K  --.-KB/s    in 0.09s   

2023-03-27 21:46:41 (416 KB/s) - ‘fmri.csv’ saved [38329/38329]

subject timepoint event region signal
0 s13 18 stim parietal -0.017552
1 s5 14 stim parietal -0.080883
2 s12 18 stim parietal -0.081033
3 s11 18 stim parietal -0.046134
4 s10 18 stim parietal -0.037970
... ... ... ... ... ...
1059 s0 8 cue frontal 0.018165
1060 s13 7 cue frontal -0.029130
1061 s12 7 cue frontal -0.004939
1062 s11 7 cue frontal -0.025367
1063 s0 0 cue parietal -0.006899

1064 rows × 5 columns

代码
文本
[10]
sns.relplot(
data=fmri, kind="line",
x="timepoint", y="signal", col="region",
hue="event", style="event",
)
plt.show()
代码
文本

当估计统计值时,seaborn将使用bootstrapping来计算置信区间,并绘制代表估计不确定性的误差线1。

seaborn中的统计估计超出了描述性统计。例如,可以通过使用lmplot()来包含线性回归模型(及其不确定性)来增强散点图1。

代码
文本
[11]
sns.lmplot(data=tips, x="total_bill", y="tip", col="time", hue="smoker")
plt.show()
代码
文本
2.2.2 分布表示

统计分析需要了解数据集中变量的分布。seaborn函数displot()支持多种可视化分布的方法,包括传统的直方图和计算密集的核密度估计。

代码
文本
[12]
sns.displot(data=tips, x="total_bill", col="time", kde=True)
plt.show()
代码
文本

seaborn 还推广一些强大但不太普遍的技术,例如计算和绘制数据的经验累积分布函数

代码
文本
[13]
sns.displot(data=tips, kind="ecdf", x="total_bill", col="time", hue="smoker", rug=True)
plt.show()
代码
文本
2.2.3 分类数据的图表

几种专门的seaborn绘图类型是面向可视化分类数据的。它们可以通过catplot()访问。这些图表提供不同级别的细化。在最细的级别上,您可能希望通过绘制“swarm”图来查看每个观察结果:这是一种散点图,它沿着分类轴调整点的位置,以便它们不重叠。”

代码
文本
[14]
sns.catplot(data=tips, kind="swarm", x="day", y="total_bill", hue="smoker")
plt.show()
代码
文本

或者,您可以使用核密度估计来表示从中抽样的点的基础分布

代码
文本
[15]
sns.catplot(data=tips, kind="violin", x="day", y="total_bill", hue="smoker", split=True)
plt.show()
代码
文本

或者,您可以仅在每个嵌套类别中显示均值及其置信区间

代码
文本
[16]
sns.catplot(data=tips, kind="bar", x="day", y="total_bill", hue="smoker")
plt.show()
代码
文本

2.3 复杂数据集的多元视图

一些 seaborn 函数结合多种绘图类型,以快速提供数据集的信息摘要。其中之一,jointplot(),专注于单个关系。它绘制两个变量之间的联合分布以及每个变量的边际分布:

代码
文本
[17]
import pandas as pd

# 以下两个操作是等效的
# penguins = sns.load_dataset("penguins")
penguins = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv')
penguins
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex
0 Adelie Torgersen 39.1 18.7 181.0 3750.0 MALE
1 Adelie Torgersen 39.5 17.4 186.0 3800.0 FEMALE
2 Adelie Torgersen 40.3 18.0 195.0 3250.0 FEMALE
3 Adelie Torgersen NaN NaN NaN NaN NaN
4 Adelie Torgersen 36.7 19.3 193.0 3450.0 FEMALE
... ... ... ... ... ... ... ...
339 Gentoo Biscoe NaN NaN NaN NaN NaN
340 Gentoo Biscoe 46.8 14.3 215.0 4850.0 FEMALE
341 Gentoo Biscoe 50.4 15.7 222.0 5750.0 MALE
342 Gentoo Biscoe 45.2 14.8 212.0 5200.0 FEMALE
343 Gentoo Biscoe 49.9 16.1 213.0 5400.0 MALE

344 rows × 7 columns

代码
文本
[18]
sns.jointplot(data=penguins, x="flipper_length_mm", y="bill_length_mm", hue="species")
plt.show()
代码
文本

另一个函数 pairplot() 则采用更广泛的视角:分别显示所有成对关系和每个变量的联合和边际分布:

代码
文本
[19]
sns.pairplot(data=penguins, hue="species")
plt.show()
代码
文本
2.3.1 用于构建图形的低级工具

这些工具通过将轴级绘图函数与管理图形布局的对象相结合,将数据集的结构链接到轴网格中。这两个元素都是公共API的一部分,您可以直接使用它们来创建只需几行代码即可创建复杂图形:

代码
文本
[20]
g = sns.PairGrid(penguins, hue="species", corner=True)
g.map_lower(sns.kdeplot, hue=None, levels=5, color=".2")
g.map_lower(sns.scatterplot, marker="+")
g.map_diag(sns.histplot, element="step", linewidth=0, kde=True)
g.add_legend(frameon=True)
g.legend.set_bbox_to_anchor((.61, .6))
plt.show()
代码
文本

2.4 默认风格和灵活的定制

seaborn 是一个用于制作统计图形的库,它提供了一些默认的图形样式,但是也允许用户进行灵活的定制

seaborn通过单个函数调用创建完整的图形:在可能的情况下,其函数将自动添加信息轴标签和图例,以解释绘图中的语义映射。

在许多情况下,seaborn还将根据数据的特征选择其参数的默认值。例如,我们到目前为止看到的颜色映射使用不同的色调(蓝色,橙色,有时是绿色)来表示分配给色调的分类变量的不同级别。当映射数字变量时,某些函数将切换到连续梯度:

代码
文本
[21]
sns.relplot(
data=penguins,
x="bill_length_mm", y="bill_depth_mm", hue="body_mass_g"
)
plt.show()
代码
文本

当你准备分享或发布你的作品时,你可能想要以比默认值更好的方式来打磨图形。seaborn 允许多个级别的自定义。它定义了多个内置主题,适用于所有图形,它的函数具有标准化的参数,可以修改每个绘图的语义映射,并且其他关键字参数传递到底层的 matplotlib 艺术家,允许更多的控制。一旦你创建了一个图,它的属性可以通过 seaborn API 和通过下降到 matplotlib 层进行精细调整来修改:

代码
文本
[22]
sns.set_theme(style="ticks", font_scale=1.25)
g = sns.relplot(
data=penguins,
x="bill_length_mm", y="bill_depth_mm", hue="body_mass_g",
palette="crest", marker="x", s=100,
)
g.set_axis_labels("Bill length (mm)", "Bill depth (mm)", labelpad=10)
g.legend.set_title("Body mass (g)")
g.figure.set_size_inches(6.5, 4.5)
g.ax.margins(.15)
g.despine(trim=True)
plt.show()
代码
文本

3 与 matplotlib 的关系

seaborn 与 matplotlib 的集成允许您在 matplotlib 支持的许多环境中使用它,包括笔记本中的探索性分析、GUI 应用程序中的实时交互以及多种栅格和矢量格式的归档输出。

虽然您可以仅使用 seaborn 函数来提高生产力,但完全定制您的图形需要一些 matplotlib 的概念和 API 知识。seaborn 新用户的学习曲线之一是知道何时下降到 matplotlib 层是必要的,以实现特定的自定义。另一方面,从 matplotlib 来的用户会发现他们的许多知识都可以转移。

Matplotlib 有一个全面而强大的 API;几乎可以更改图形的任何属性以满足您的喜好。seaborn 的高级接口和 matplotlib 的深度可定制性的组合将允许您快速探索数据,并创建可以定制为出版质量最终产品的图形。

Received message. seaborn 与 matplotlib 的集成允许您在 matplotlib 支持的许多环境中使用它,包括笔记本中的探索性分析、GUI 应用程序中的实时交互以及多种栅格和矢量格式的归档输出。 虽然您可以仅使用 seaborn 函数来提高生产力,但完全定制您的图形需要一些 matplotlib 的概念和 API 知识。seaborn 新用户的学习曲线之一是知道何时下降到 matplotlib 层是必要的,以实现特定的自定义。另一方面,从 matplotlib 来的用户会发现他们的许多知识都可以转移。 Matplotlib 有一个全面而强大的 API;几乎可以更改图形的任何属性以满足您的喜好。seaborn 的高级接口和 matplotlib 的深度可定制性的组合将允许您快速探索数据,并创建可以定制为出版质量最终产品的图形。

代码
文本

总结

在本教程中,您学习了在 seaborn 的一些基础方法。

具体而言,您了解到:

  • 根据简单示例快速进行 seaborn 绘图
  • 绘制统计估计、分布表示、分类数据的图表
  • 使用 seaborn 对复杂数据集进行多元视图绘制
  • 如何使用 seaborn 默认的绘图主题以及自定义你的主题

你有什么问题吗? 欢迎与我们联系 bohrium@dp.tech

代码
文本

进一步阅读

如果您希望更深入学习 seaborn 及 Python 数据可视化,本节提供有关该主题的更多资源。

书籍

seaborn 项目

代码
文本
Tutorial
Seaborn
Data Visualize
TutorialSeabornData Visualize
已赞6
本文被以下合集收录
使用 Python 快速开始机器学习
MileAway
更新于 2024-07-25
7 篇25 人关注
测试合集文章列表100篇
xingyanshi@dp.tech很长的名字xingyanshi@dp.tech很长的名字很长的
更新于 2024-08-04
104 篇2 人关注
推荐阅读
公开
快速开始 ABACUS|自洽 能带 态密度 结构优化
ABACUSDFTChinesesTutorial
ABACUSDFTChinesesTutorial
MileAway
发布于 2023-06-12
19 赞27 转存文件3 评论
公开
未命名
测试7
测试7
Esplendo
发布于 2024-05-16