Python绘图总结(seaborn篇)之概况

本文介绍了使用 Seaborn 库提升 Matplotlib 图表的美观度及可读性的方法,包括条形图、堆叠条形图、柱状图、密度图、散点图等各类图表的绘制技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导入seaborn会改变matlotlib默认的颜色和绘图样式,提高可读性和美感。即使不适用seaborn的API,也可以利用seaborn来提高可视化的效果。
# 使用该魔法,不用写plt.show(),以及可以边写边运行
# %matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn
1
2
3
4
5
6
df = pd.DataFrame(np.random.rand(6, 4),
                  index=['one', 'two', 'three', 'four', 'five', 'six'],
                  columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'))
df
1
2
3
4
Genus A B C D
one 0.124602 0.546970 0.855259 0.206495
two 0.376432 0.418493 0.646991 0.776206
three 0.382580 0.011980 0.842492 0.972879
four 0.482981 0.038816 0.157038 0.765201
five 0.789604 0.576519 0.643277 0.880073
six 0.180868 0.935182 0.392939 0.364351
# 导入seaborn会改变matlotlib默认的颜色和绘图样式
df.plot.bar()   
1
2
这里写图片描述


注意这里DataFrame列名的”Genus”,被作为图例。


我们可以设定stacked=True,令条形图堆叠起来,能让每一行的所有值都被堆起来:


#  横向barh
df.plot.barh(stacked=True, alpha=0.5)
1
2
这里写图片描述


一个小窍门,在画series的值出现的频率的条形图时,可以使用value_counts: s.value_counts().plot.bar()
之前我们用到过tipping(小费)数据集,假设我们想做一个堆叠的条形图,来表示在每一天,每一个大小不同的组(party)中,数据点的百分比。用read_csv导入数据,并按天数(day)和组大小(party size)做一个交叉报表(cross-tabulation):


tips = pd.read_csv('../examples/tips.csv')
tips.head()
1
2
total_bill tip smoker day time size
0 16.99 1.01 No Sun Dinner 2
1 10.34 1.66 No Sun Dinner 3
2 21.01 3.50 No Sun Dinner 3
3 23.68 3.31 No Sun Dinner 2
4 24.59 3.61 No Sun Dinner 4
# pd.crosstab()  表示两个元素交叉表
party_counts = pd.crosstab(tips['day'], tips['size']) 
party_counts
1
2
3
size 1 2 3 4 5 6
day
Fri 1 16 1 1 0 0
Sat 2 53 18 13 1 0
Sun 0 39 15 18 3 1
Thur 1 48 4 5 1 3
# 大于1人小于6人
party_counts = party_counts.loc[:, 2:5]
party_counts
1
2
3
size 2 3 4 5
day
Fri 16 1 1 0
Sat 53 18 13 1
Sun 39 15 18 3
Thur 48 4 5 1
标准化一下,让每一行的和变为1,然后绘图:


# Normalize to sum to 1
party_pcts = party_counts.div(party_counts.sum(1), axis=0)
party_pcts
1
2
3
size 2 3 4 5
day
Fri 0.888889 0.055556 0.055556 0.000000
Sat 0.623529 0.211765 0.152941 0.011765
Sun 0.520000 0.200000 0.240000 0.040000
Thur 0.827586 0.068966 0.086207 0.017241
party_pcts.plot.bar()
1
这里写图片描述


这样我们可以看出来,在周末的时候组大小(party size)是增大的。


对于需要汇总的数据,使用seaborn能方便很多。让我们试一下用seaborn,按day来查看tipping percentage(小费百分比):


import seaborn as sns


tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip'])
tips.head()
1
2
3
4
total_bill tip smoker day time size tip_pct
0 16.99 1.01 No Sun Dinner 2 0.063204
1 10.34 1.66 No Sun Dinner 3 0.191244
2 21.01 3.50 No Sun Dinner 3 0.199886
3 23.68 3.31 No Sun Dinner 2 0.162494
4 24.59 3.61 No Sun Dinner 4 0.172069
sns.barplot(x='tip_pct', y='day', data=tips, orient='h')
1
这里写图片描述


seaborn的绘图函数中有一个data参数,这里可以导入pandas的DataFrame。其他参数指的是列名。因为每一天(比如一个固定的周六)可能会有多个不同的值,所以条形图表示的是tip_pct的平均值。条形图上的黑线表示95%的置信区间(confidence interval)(这个可以通过可选参数进行更改)。


seaborn.barplot有一个hue选项,这个能让我们通过一个额外的类别值把数据分开:


sns.set_style("ticks") # 我们可以换一个样式
# sns.set_style("white")
1
2
sns.barplot(x='tip_pct', y='day', hue='time', data=tips, orient='h')
1
这里写图片描述


注意seaborn会自动更改绘图的外观:默认的调色板,绘图背景,网格颜色。我们可以自己设定不同的绘图外观,通过seaborn.set:


sns.set(style='whitegrid')
1
### Histograms and Density Plots(柱状图和密度图)¶ 柱状图是一种条形图,不过值的频率是分割式的。数据点被分割为,离散的甚至是隔开的bin(BIN是储存箱、存放箱、垃圾箱的意思,中文实在是不好翻译,我把它理解为一个小柱子,之后就直接用bin了),而且每个bin中的数据点的数量会被画出来。用上面的tipping数据集,我们可以用plot.hist做一个柱状图来表示小费(tip)占总费用(total bill)的比例:
tips['tip_pct'].plot.hist(bins=50)
1
这里写图片描述


另一种相关的绘图类型是density plot(密度图),这个是用来计算观测数据中,连续概率分布的推测值。通常的步骤是用一组混合的“kernels”(核)来近似这个分布————核指的是,像正态分布一样的简单分布。因此,概率图也经常被叫做kernel density estimate(KDE, 核密度估计)图。用plot.kde,通过conventional mixture-of-normals estimate(常规混合估计 
)制作一个密度图:


tips['tip_pct'].plot.density()
1
这里写图片描述


seaborn能更方便地绘制柱状图和概率图,通过distplot方法,这个方法可以同时绘制一个柱状图和a continuous density estimate(一个连续密度估计)。举个例子,考虑一个bimodal distribution(双峰分布,二项分布),它由连个不同的标准正态分布组成:


comp1 = np.random.normal(0, 1, size=200)
comp2 = np.random.normal(10, 2, size=200)
values = pd.Series(np.concatenate([comp1, comp2]))
1
2
3
values[:10]
1
0 0.739053 1 0.153858 2 -0.154554 3 0.794769 4 -0.714605 5 -2.284874 6 0.309162 7 -0.042779 8 -0.127593 9 -0.247470 dtype: float64
sns.distplot(values, bins=100, color='k')
1
这里写图片描述


Scatter or Point Plots(散点图或点图)


散点图对于检查二维数据之间的关系是非常有用的。例如,我们导入macrodata数据集,选一些参数,然后计算log differences(对数差分)


macro = pd.read_csv('../examples/macrodata.csv')
macro.head()
1
2
year quarter realgdp realcons realinv realgovt realdpi cpi m1 tbilrate unemp pop infl realint
0 1959.0 1.0 2710.349 1707.4 286.898 470.045 1886.9 28.98 139.7 2.82 5.8 177.146 0.00 0.00
1 1959.0 2.0 2778.801 1733.7 310.859 481.301 1919.7 29.15 141.7 3.08 5.1 177.830 2.34 0.74
2 1959.0 3.0 2775.488 1751.8 289.226 491.260 1916.4 29.35 140.5 3.82 5.3 178.657 2.74 1.09
3 1959.0 4.0 2785.204 1753.7 299.356 484.052 1931.3 29.37 140.0 4.33 5.6 179.386 0.27 4.06
4 1960.0 1.0 2847.699 1770.5 331.722 462.199 1955.5 29.54 139.6 3.50 5.2 180.007 2.31 1.19
data = macro[['cpi', 'm1', 'tbilrate', 'unemp']]
data.head()
1
2
cpi m1 tbilrate unemp
0 28.98 139.7 2.82 5.8
1 29.15 141.7 3.08 5.1
2 29.35 140.5 3.82 5.3
3 29.37 140.0 4.33 5.6
4 29.54 139.6 3.50 5.2
trans_data = np.log(data).diff().dropna()
trans_data[-5:]
1
2
cpi m1 tbilrate unemp
198 -0.007904 0.045361 -0.396881 0.105361
199 -0.021979 0.066753 -2.277267 0.139762
200 0.002340 0.010286 0.606136 0.160343
201 0.008419 0.037461 -0.200671 0.127339
202 0.008894 0.012202 -0.405465 0.042560
关于对数差分译者找到的一些资料:



- 取对数(log):缩小差距,减少异方差性 
- 差分:非平缓数据变平稳的技能


2 是原始序列的对数增长率,而且这么处理后序列会更平稳



对于不平稳的时间序列,我们可以通过差分的方法使它平稳,但是差分之后的问题是有的经济意义就无法直观解释了,所以我们又有了构建协整关系这一方法。


然后我们可以利用seaborn的regplot方法,它可以产生一个散点图并拟合一条回归线:


sns.set_style("whitegrid")
sns.regplot('m1', 'unemp', data=trans_data)
1
2
这里写图片描述


在数据探索阶段,散点图能把一组变量之间所有的散点图都画出来,这种图被称之为pairs plot(多变量图)或scatter plot matrix(散点图矩阵)。画这样的图很麻烦,所以seaborn有一个非常方便的pairplot函数,这个函数可以把每一个参数的柱状图或密度估计画在对角线上:


sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2})
1
这里写图片描述


这里要注意一下plot_kws关键字。这个让我们能导入设置选项,用来控制非对角线上的绘图。查看seaborn.pairplot的字符串文档查看更多的设定选项


sns.pairplot?
1
### Facet Grids and Categorical Data(多面网格和类别数据) 如果遇到一些数据集,需要额外分组的维度,该怎么办?一个方法是使用类别变量来把数据可视化,利用facet grid(多面网格)。seaborn有一个有用的内建函数factorplot,能简化制作各种多面图的过程:
sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker', 
               kind='bar', data=tips[tips.tip_pct < 1])
1
2
这里写图片描述


在一个facet(面)内,不是通过time和不同的柱状颜色来分组,我们也能通过添加给每一个time值添加一行的方式来扩展多面网格:


tips[tips.tip_pct < 1].head()
1
total_bill tip smoker day time size tip_pct
0 16.99 1.01 No Sun Dinner 2 0.063204
1 10.34 1.66 No Sun Dinner 3 0.191244
2 21.01 3.50 No Sun Dinner 3 0.199886
3 23.68 3.31 No Sun Dinner 2 0.162494
4 24.59 3.61 No Sun Dinner 4 0.172069
sns.factorplot(x='day', y='tip_pct', row='time',col='smoker', kind='bar', data=tips[tips.tip_pct< 1])
1
这里写图片描述


factorplot支持其他一些绘图类型,是否有用取决于我们想要如何展示。例如,box plots(箱线图,可以展示中位数,分位数和利群店)可能是一种有效的视觉类型:


sns.factorplot(x='tip_pct', y='day', kind='box', data=tips[tips.tip_pct < 0.5])
1
这里写图片描述


通过seaborn.FacetGrid,我们可以创建自己的多面网格图。更多信息请查看seaborn的文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值