数据可视化就是使用图形图表等方式来呈现数据,图形图表能够高效清晰地表达数据包含的信息。数据可视化在各个领域都得到了广泛的应用,例如,产品销售数据的可视化,统计样本数据可视化,机器学习数据可视化等。
Python有很多非常优秀易用的数据可视化的库,其中最著名的要数matplotlib了,它有着十几年的历史,至今仍然是Python使用者最常用的画图库。
Seaborn跟matplotlib最大的区别就是它的默认绘图风格和色彩搭配都具有现代美感,其实是在matplotlib的基础上进行了更高级的API封装,让你能用更少的代码去调用 matplotlib的方法,从而使得作图更加容易,在大多数情况下使用seaborn就能做出很具有吸引力的图,而使用matplotlib就能制作具有更多特色的图。应该把Seaborn视为matplotlib的补充,而不是替代物。
安装
pip install matplotlib
pip install seaborn
参数配置
matplotlib.pyplot使用rc配置文件来自定义图形的各种默认属性,称之为rc配置或rc参数。通过rc参数可以修改默认的属性,包括窗体大小、每英寸的点数、线条宽度、颜色、样式、坐标轴、坐标和网络属性、文本、字体等。
经过优化配置后图表会更美观。
#-*- coding:utf-8 -*-
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
# 一些默认配置,使得图表更美观
large = 22; med = 16; small = 12
params = {'axes.titlesize': large,
'legend.fontsize': med,
'figure.figsize': (16, 10),
'axes.labelsize': med,
'axes.titlesize': med,
'xtick.labelsize': med,
'ytick.labelsize': med,
'figure.titlesize': large}
plt.rcParams.update(params)
plt.style.use('seaborn-whitegrid')
sns.set_style("white")
# 设置matplotlib正常显示中文
plt.rcParams['font.sans-serif']=['SimHei'] # 用黑体显示中文
plt.rcParams['axes.unicode_minus']=False
1、直方图
直方图(Histogram),又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。
def plot_dist(title, x):
'''
绘制质量分布图
INPUT -> 标题, 数据集(单变量)
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.distplot(x, hist=True, kde=True, rug=True) # 前两个代表直方图和一元核密度估计图,默认就是True;rug是在最下方显示出频率情况,默认为False
plt.title(title, fontsize=22)
plt.show()
# 生成一些随机数
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
plot_dist('测试图', s)
2、核密度估计图
核密度估计(kernel density estimation)是在概率论中用来估计未知的密度函数,属于非参数检验方法之一。通过核密度估计图可以比较直观的看出数据样本本身的分布特征。
def plot_1kde(title, x, cumulative=False):
'''
绘制一元核密度估计图
INPUT -> 标题, 数据集(单变量)
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.kdeplot(x, cumulative=cumulative, shade=True, color='r') # cumulative为密度累计, shade表示线下颜色为阴影, color表示颜色是红色
plt.title(title, fontsize=22)
plt.show()
def plot_2kde(title, x, y):
'''
绘制二元核密度估计图
INPUT -> 标题, 字段1, 字段2
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.kdeplot(x, y, shade=True, cbar=True) # cbar表示颜色棒
plt.title(title, fontsize=22)
plt.show()
# 生成一些随机数
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
h = pd.Series(rs.randn(70) * 100)
plot_1kde('测试图', s)
plot_2kde('测试图2', s, h)
3、散点图
def plot_joingrid(x, y):
'''
绘制两个变量关系图
INPUT -> 字段1, 字段2
'''
g = sns.jointplot(x=x, y=y, # 设置xy轴,显示columns名称
color = 'k', # 设置颜色
s = 50, edgecolor="w",linewidth=1, # 设置散点大小、边缘线颜色及宽度(只针对scatter)
kind = 'scatter', # 设置类型:“scatter”、“reg”、“resid”、“kde”、“hex”
space = 0.2, # 设置散点图和布局图的间距
size = 5, # 图表大小(自动调整为正方形)
ratio = 4, # 散点图与布局图高度比,整型
marginal_kws=dict(bins=15, rug=True) # 设置柱状图箱数,是否设置rug
)
g = g.set_axis_labels("X","Y")
plt.show()
# 生成一些随机数
rs = np.random.RandomState(80)
s = pd.Series(rs.randn(70) * 100)
h = pd.Series(rs.randn(70) * 100)
plot_joingrid(s, h)
4、分类/分簇散点图
Stripplot按照不同类别对样本数据进行分布散点图绘制。
Swarmplot也是绘制散点图,但它会通过算法,在类别坐标轴的方向上延展那些原本重合的点,与通过Stripplot.jitter属性增加抖动有异曲同工之妙。
def plot_pairgrid1(x, y):
'''
绘制分类散点图
INPUT -> 分组列, 统计列
'''
colors = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
sns.stripplot(x=x, # 设置分组统计字段
y=y, # 数据分布统计字段
# 这里xy数据对调,会使得散点图横向分布
jitter=0.05, # jitter代表设置抖动
edgecolor = 'w', linewidth = 1, marker = 'o',
palette=colors)
plt.show()
def plot_pairgrid2(x, y):
'''
绘制分簇散点图
INPUT -> 分组列, 统计列
'''
colors = ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436c7', '#F04864']
sns.swarmplot(x=x, # 设置分组统计字段
y=y, # 数据分布统计字段
# 这里xy数据对调,会使得散点图横向分布
edgecolor = 'w', linewidth = 1, marker = 'o',
palette=colors)
plt.show()
tips = sns.load_dataset('tips')
plot_pairgrid1(tips['day'], tips['total_bill'])
plot_pairgrid2(tips['day'], tips['total_bill'])
5、箱体图/小提琴图/LV图
通过Boxplot可以看到数据的最大值、上四分位数Q3、中位数、下四分位数Q1、最小值和异常值的分布。
Violinplot与Boxplot相似,但其图形如同小提琴般,可以更好地展现出数据的量化形态。
lvplot(信值图)是箱线图和提琴图的混合,但是对于大数据集有更强的缩放能力,渲染速度更快。
def plot_box(x, y):
'''
绘制箱体图
INPUT -> 字段1, 字段2
'''
sns.boxplot(x = x, y = y,
# data = df,
linewidth = 2, #线宽
width = 0.8, # 箱之间的间隔比例
fliersize = 3, #异常点大小
whis = 1.5, #设置IQR
notch = True, #设置是否以中值做凹槽
order = {'Thur','Fri','Sat','Sun'}, # 筛选类别
palette='Set2' #设置调色板
)
#可以添加散点图
sns.swarmplot(x = x, y = y, color = 'k', size = 3, alpha = 0.8)
plt.show()
def plot_violin(x, y):
'''
绘制小提琴图
INPUT -> 字段1, 字段2
'''
sns.violinplot(x = x, y = y,
# data = df,
linewidth = 2, # 线宽
width = 0.8, # 箱之间的间隔比例
fliersize = 3, # 异常点大小
whis = 1.5, # 设置IQR
notch = True, # 设置是否以中值做凹槽
scale = 'count', # 测度小提琴图的宽度: area-面积相同,count-按照样本数量决定宽度,width-宽度一样
order = {'Thur','Fri','Sat','Sun'}, # 筛选类别
palette='Set2', #设置调色板
# hue = z, # 按z再细分
# split = True, # 设置是否按z拆分小提琴图
)
plt.show()
def plot_lv(x, y):
'''
绘制LV图(信值图)
INPUT -> 字段1, 字段2
'''
sns.lvplot(x = x, y = y,
# data = df,
palette = 'mako',
linewidth = 12, # 线宽
width = 0.8, # 箱之间的间隔比例
scale = 'area', # 设置框的大小:'linear'、'exonential'、'area'
k_depth = 'proportion' # 设置框的数量:'proportion','tukey','trustworthy'
)
plt.show()
tips = sns.load_dataset('tips')
plot_box(tips['day'], tips['total_bill'])
plot_violin(tips['day'], tips['total_bill'])
plot_lv(tips['day'], tips['total_bill'])
6、矩阵图
矩阵图可以用于绘制展现数据集内多个变量之间两两关系。
def plot_pairgrid(df, mark=None):
'''
绘制矩阵图
INPUT -> 数据集, 分类标签
'''
g = sns.PairGrid(data=df,
hue=mark)
# vars=["sepal_width", "sepal_length"] vars:需要组合的数据字段
g = g.map_diag(sns.kdeplot, lw=3, legend=False) # 单变量
# g = g.map_offdiag(plt.scatter)
g = g.map_upper(plt.scatter)
g = g.map_lower(sns.kdeplot, cmap="Blues_d")
for ax in g.axes.flat:
plt.setp(ax.get_xticklabels(), rotation=45)
plt.show()
7、热力图
seaborn中的热力图,有利于数据特征的关联性表示
def plot_heatmap(title, df):
'''
绘制热力图
INPUT -> 标题, 数据集
'''
plt.figure(figsize=(12,10), dpi= 80)
sns.heatmap(df.corr(), xticklabels=df.corr().columns, yticklabels=df.corr().columns, cmap='RdYlGn', center=0, annot=True)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.title(title, fontsize=22)
plt.show()
6、时序图
def plot_timeseries(x, y, title, df):
'''
绘制时序图
INPUT -> 时间字段, 数量字段, 标题, 数据集
'''
plt.figure(figsize=(16,10), dpi= 80)
plt.plot(x, y, data=df, color='tab:red')
plt.ylim(0, 1000) # y轴显示范围
xtick_location = df.index.tolist()[::12] # x轴取最近12个
xtick_labels = [i[-4:] for i in df.date.tolist()[::12]] # 年份
plt.xticks(ticks=xtick_location, labels=xtick_labels, rotation=0, fontsize=12, horizontalalignment='center', alpha=.7)
plt.yticks(fontsize=12, alpha=.7)
plt.title(title, fontsize=22)
plt.grid(axis='both', alpha=.3)
# 移除边框
plt.gca().spines["top"].set_alpha(0.0)
plt.gca().spines["bottom"].set_alpha(0.3)
plt.gca().spines["right"].set_alpha(0.0)
plt.gca().spines["left"].set_alpha(0.3)
plt.show()