matplotlib与seaborn常用绘图及设置

本文详细介绍了matplotlib和seaborn库在数据可视化中的应用,包括matplotlib的3种绘图方式、常见图表如双系列柱状图、3D图、小提琴图、填充图和动态图的绘制方法,以及seaborn的风格设置、离散和连续变量的统计分析图表。此外,还涵盖了中文乱码问题的解决和如何创建多图网格布局。

matplotlib与seaborn常用绘图及设置

前言:日常工作绘图记录,以备不时查询之需


一、matplotlib

1、matplotlib 3种绘图方式

# 导包
import matplotlib.pyplot as plt
import seaborn as sns

# 绘图数据
x,y = range(5),range(5)

# 第一种方式(直接绘图,只有一张图)
plt.figure(figsize=(3,2)) # 调整画布大小
plt.scatter(x,y)  # 绘制散点图,绘制其他图像参考【matplotlib 绘图总结图解】
plt.title('第一种绘图方式') # 添加标题,中文显示乱码参考【matplotlib 绘图问题处理】
plt.show() 

# 第2种方式(绘画子图)
plt.subplot(1,2,1) #直接申明子图位置
plt.bar(x,y) # 绘制柱状图,绘制其他图像参考【matplotlib 绘图总结图解】
plt.title('子图1标题')
plt.subplot(1,2,2)
plt.plot(x,y) # 绘制折线图
plt.suptitle('第2种绘图方式') # 所有子图总标题
plt.show()

# 第3种方式(直接创建所有子图,然后再单独绘制)
fig,(ax1,ax2) = plt.subplots(1,2)
fig.set_size_inches(6,3)  # 设置画布大小
ax1.fill_betweenx(y,0,x) # 填充图 fill_betweenx(self, y, x1, x2=0, where=None,step=None, interpolate=False, **kwargs)
ax2.fill_between(x,0,y)  # .fill_between(self, x, y1, y2=0, where=None, interpolate=False,step=None, **kwargs)
ax1.text(3,0.5,'添加文本',color='g') # .text(x,y,str,),图中加入文本
ax2.axvline(3,0,5,color='r') # axvline(self, x=0, ymin=0, ymax=1, **kwargs) 添加垂直于轴水平线
plt.suptitle('第三种绘图方式')
plt.show()

结果如下:

12

26

2、matplotib 日常使用绘图

2.1 双系列柱状图(用于系列对比/趋势变化)
import matplotlib.pyplot as plt

# 1.双系列柱状图(用于系列对比/趋势变化)
x = ['测试1','测试2','xxxx3']
y1 = [1,2,3]
y2 = [4,5,6]

plt.figure(figsize=(8,4))
plt.bar(x=x,height=y1,width=-0.4,align='edge',label='y1') # 调整柱子位置
plt.bar(x=x,height=y2,width=0.4,align='edge',label='y2')
# 设置刻度标签名
plt.yticks(ticks=[0,1,2,3,4,5,6],labels=['刻度0','刻度1','刻度2','刻度3','刻度4','刻度5','刻度6'])
plt.xticks(rotation=45) # 调整x轴刻度标签转向
plt.legend() # 图例设置

3

2.2 三维图绘制(展示数据空间分布,可用于PCA降维后查看数据分布)
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

plt.figure(figsize=(12,5))
         
a = np.linspace(-5,5,num=110) # 等差数列
b = np.linspace(-5,5,num=110)
x,y = np.meshgrid(a,b) # 生成网格数据
L1 = np.abs(x)+np.abs(y) 
L2 = np.sqrt(np.square(x)+np.square(y))
         
# 设置子图1
ax = plt.subplot(1,2,1,projection='3d')
ax.plot_surface(x,y,L1,cmap='Reds') # 绘制表面
ax.plot_surface(x,y,L2,cmap='Greys') 
# ax.contourf(x,y,l1,cmap='Reds') # 绘制3d等高线
l1_pos = plt.Rectangle((0,0),1,1,fc='r') # 设置3维图例
l2_pos = plt.Rectangle((0,0),1,1,fc='dimgray')
ax.legend([l1_pos,l2_pos],['L1正则','L2正则'])
         
         
# 设置子图2
ax1 = plt.subplot(1,2,2,projection='3d')
a1 = np.linspace(-5,5,num=10)
b1 = np.linspace(-5,5,num=10)
x1,y1 = np.meshgrid(a1,b1)
c1 = np.abs(x1)+np.abs(y1)
c2 = np.sqrt(np.square(x1)+np.square(y1))
ax1.scatter3D(xs=x1,ys=y1,zs=c1,label='数据1')
ax1.scatter3D(xs=x1,ys=y1,zs=c2,label='数据2')
ax1.legend()
ax1.view_init(elev=60,azim=30) # 调整3维图像显示角度

4

2.3 小提琴图(显示一组数据分布,机器学习二分类任务,各个特征数据分布对比)
import matplotlib.pyplot as plt
import pandas as pd
import random


fig,axs = plt.subplots(nrows=1,ncols=3)
fig.set_size_inches(10,4) # 修改画布尺寸(单位:英寸)
fig.subplots_adjust(wspace=0.5) # 调整子图间距
         
test_data = pd.DataFrame({'feature1':random.choices(range(10,30),k=100)
                                   ,'feature2':random.choices(range(10,30),k=100)
                                   ,'feature3':random.choices(range(10,30),k=100)
                                   ,'label':[0 for i in range(100)]}).append(
                              pd.DataFrame({'feature1':random.choices(range(25,45),k=100)
                                   ,'feature2':random.choices(range(25,45),k=100)
                                   ,'feature3':random.choices(range(25,45),k=100)
                                   ,'label':[1 for i in range(100)]}))
for i in range(3):           
   # 绘制0类样本个特征小提琴图(数据分布)    
   axs[i].violinplot(test_data.loc[test_data['label']==0,'feature'+str(i+1)],positions=[-2],widths=2,showmeans=True,showextrema=False)

   # 对应位置绘制1类样本个特征小提琴图(数据分布)          
   axs[i].violinplot(test_data.loc[test_data['label']==1,'feature'+str(i+1)],positions=[2],widths=2,showmeans=True,showextrema=False)
   axs[i].set_title('feature'+str(i+1))
   axs[i].set_xlabel(xlabel='0类特征             1类特征')  # 设置坐标轴标签名称

5

2.4 填充图或面积图(聚类分析时,可查看聚类效果)
import matplotlib.pyplot as plt
from sklearn.datasets import make_biclusters
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples
from sklearn.metrics import silhouette_score

# 创建分类数据
dataset_test = make_biclusters(shape=(1000,3),n_clusters=3,noise=0.1,minval=0,maxval=1,random_state=42)[0]
# 测试数据展示
fig = plt.figure(figsize=(12,5))
ax = fig.add_subplot(projection='3d') # 添加3d坐标系
ax.scatter(xs=dataset_test[:,0],ys=dataset_test[:,1],zs=dataset_test[:,2])
         
# 聚类效果函数
def make_clusters_effect(n_clusters=3):
    kmeans = KMeans(n_clusters=n_clusters)
    kmeans = kmeans.fit(X=dataset_test)
    res = kmeans.predict(dataset_test)
    silhouette_mean = silhouette_score(X=dataset_test,labels=res) # 总体轮廓系数(或整体轮廓系数平均值)
    silhouette_per = silhouette_samples(X=dataset_test,labels=res) # 每个样本轮廓系数
             
    fig = plt.figure(figsize=(12,5))
    # 绘制子图1
    plt.subplot(1,2,1)
    init_y = 0
    plt.xlim(-0.2,1) # 设置x轴刻度范围
    for i in range(n_clusters):
        plt.fill_betweenx(y=range(init_y,init_y+len(silhouette_per[res==i])),x1=sorted(silhouette_per[res==i]))
        plt.text(x=-0.1,y=(2*init_y+len(silhouette_per[res==i]))/2,s=f'{i}类')
        init_y = init_y+len(silhouette_per[res==i])+10
    plt.vlines(x=silhouette_mean,ymin=0,ymax=1000,label='总轮廓系数',colors='r') # 设置水平线
    plt.legend()
    # 绘制子图2
    ax = plt.subplot(1,2,2,projection='3d')
    for i in range(n_clusters):
        ax.scatter(xs=dataset_test[res==i,0],ys=dataset_test[res==i,1],zs=dataset_test[res==i,2],label=f'{i}类')
    ax.legend()
    fig.suptitle(f'聚类为{n_clusters}类效果图') # 设置所有子图总标题
             
# 分别查看聚类为3~5 的聚类效果(明显数据合理聚类为3类,每一类中均有一部分样本轮廓系数在总体轮廓系数之上)
for i in range(3,6):
    make_clusters_effect(i) 

6

2.5 动态图(git保存,可以动态实时查看深度学习目标函数损失情况)
import matplotlib.pyplot as plt
from matplotlib import animation
import numpy as np


fig,axs = plt.subplots(1,2)
# fig.set_size_inches(w=12,h=8)
         
x = np.arange(0,2*np.pi,0.01)
         
line1,=axs[0].plot(x,np.sin(x),c='C2')
line2,=axs[1].plot(x,np.cos(x),c='C2')
# 图像初始化函数
def init():
    axs[0].set_title('sin_images');axs[1].set_title('cos_images') # 设置子图标题
    axs[0].set_xlim((0,10));axs[1].set_xlim((0,10)) # 设置x轴刻度范围
    # axs[0].axis('off');axs[1].axis('off') # 取消坐标轴
    # axs[0].set_xticks(range(1,11));axs[1].set_xticks(range(1,11)) # 设置刻度值
             
# 动态更新函数 
def update(i):
    global x
    x+=i
    line1.set_ydata(np.sin(x)) # line1.set_ydata(y1) # 修改x轴,y轴数据
    line2.set_ydata(np.cos(x))
             
ani = animation.FuncAnimation(fig=fig,func=update,
                                       frames=np.linspace(0,1),
                                       init_func=init,interval=200
                                      )
         
# 将动态图保存为.gif
ani.save('./test.gif',writer='pillow')

7

2.6 修改坐标系显隐性及坐标轴位置
import matplotlib.pyplot as plt
import numpy as np

data=np.array([[1,1,0],[-1,-1,0],[1,-1,1],[-1,1,1]])
plt.figure(figsize=(6,3))
axes=plt.subplot(1,2,1)
# 设置坐标轴显隐性
axes.spines[['top','right']].set_visible(False)
# 改变坐标轴位置
axes.spines['left'].set_position(("data", 0))
axes.spines['bottom'].set_position(("data", 0))
axes.scatter(data[data[:,2]==0,0],data[data[:,2]==0,1],c='red')
axes.scatter(data[data[:,2]==1,0],data[data[:,2]==1,1],c='blue')
axes.set_xticks([-1,0,1]);axes.set_yticks([-1,1])

8

3、matplotlib 绘图问题处理

3.1 中文与负号显示乱码问题
  • 拷贝字体文件到mat库指定路径下 (win系统下从路径’C:\Windows\Fonts’下拷贝字体文件(黑体就行simhei.ttf),将拷贝字体文件放到“xxx\python3.9\Lib\site-packages\matplotlib\mpl-data\fonts\ttf”下)

    9

  • 修改mat配置文件(重新启动python内核)

    在路径“ xxx\python3.9\Lib\site-packages\matplotlib\mpl-data”下打开matplotlibrc文件(可以使用NodePad++)
      
    1. 解开'font.family'注释,使用 sans-serif 系列字体
    2. 解开"font.sans-serif"注释,在 sans-serif 系列字体前加上 “simhei”(或其它放入'xx/ttf/'路径内的字体)
    3. 解开"axes.unicode_minus"注释,并设置“axes.unicode_minus:False ” 显示负数
    

10

二、seaborn

1、seaborn 简介

个人理解: seaborn 在matplotlib的基础上,对matplolib 更高级的封装,绘图技巧和matplotlib差不多,但绘图代码更少,图像更炫(相应地api参数就比较复杂)。输入数据为DataFrame.

2、seaborn 绘图案例

2.1 设置绘图整体风格、环境(字体大小)和调色板
import seaborn as sns
# 整体预设计 风格、环境、颜色
# 1. 风格 one of {darkgrid, whitegrid, dark, white, ticks}
sns.set_style(style='darkgrid') # 设置整体风格
sns.axes_style(style='darkgrid') # 针对单个axes 进行设置

# 2. 绘图环境 one of {paper, notebook, talk, poster} 从小到大图形、字体缩放
sns.set_context(context='notebook')

# 3. 颜色(调色板)
sns.palplot(sns.color_palette(palette='magma',n_colors=8)) # 可使用matplotlib的color或colormap

11

2.2 离散变量统计分析
2.2.1 分类散点图(stripplot)、箱型图(boxplot)、小提琴图(violinplot)、点图(pointplot),柱状图(barplot)等
from sklearn.datasets import load_iris # 鸢尾花数据集
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

# 加载数据
tips = pd.read_csv('./data/tips.csv') # 官方案例数据

# 小费数据集如下
'''
	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
'''

iris = pd.DataFrame(data=load_iris().data,columns=load_iris().feature_names) 
iris['target'] = load_iris().target

# 鸢尾花数据集如下
'''
	sepal length (cm)	sepal width (cm)	petal length (cm)	petal width (cm)	target
0	5.1	3.5	1.4	0.2	0
1	4.9	3.0	1.4	0.2	0
2	4.7	3.2	1.3	0.2	0
3	4.6	3.1	1.5	0.2	0
4	5.0	3.6	1.4	0.2	0
'''


## 分类变量分析 ------------------------------------------------------------------
fig = plt.figure(figsize=(12,15))
fig.subplots_adjust(hspace=0.5) # 调整子图间距

# sns.stripplot 分类散点图 (strip : 条纹)
plt.subplot(421)
sns.stripplot(data=tips,x='day',y='total_bill',jitter=0.2,hue='sex') # jitter : 抖动
plt.title('sns.stripplot')

# sns.swarmplot 分类一字抖动散点图(swarm:一大群(蜜蜂等昆虫);一大批(向同方向移动的人))
plt.subplot(422)
sns.swarmplot(data=tips,x='day',y='total_bill',hue='sex')
plt.title('sns.swarmplot')

# sns.boxplot 箱型图
plt.subplot(423)
sns.boxplot(data=tips,x='day',y='total_bill')
plt.title('sns.boxplot')

# sns.boxenplot 增强版 箱型图
plt.subplot(424)
sns.boxenplot(data=tips,x='day',y='total_bill')
plt.title('sns.boxenplot')

# sns.violinplot 小提琴图
plt.subplot(425)
sns.violinplot(data=tips,x='day',y='total_bill',order=['Thur','Fri','Sat','Sun'])
plt.title('sns.violinplot')

# sns.pointplot 均值点图
plt.subplot(426)
sns.pointplot(data=tips,x='day',y='total_bill',order=['Thur','Fri','Sat','Sun'])
plt.title('sns.pointplot')

# sns.barplot 均值柱状图
plt.subplot(427)
sns.barplot(data=tips,x='day',y='total_bill',order=['Thur','Fri','Sat','Sun'],)
plt.title('sns.barplot')

# sns.countplot 词频柱状图
plt.subplot(428)
sns.countplot(data=tips,x='day',order=['Thur','Fri','Sat','Sun'],)
plt.title('sns.countplot')

12

2.2.2 构建结构化多绘图网格(FacetGrid、catplot=FacetGrid+stripplot)
## sns.FacetGrid  构建结构化多绘图网格(构建不同维度子图)
# FacetGrid 不同维度子图
plt.figure(figsize=(12,5))
def custom_fn(*args,**kwargs):
    sns.countplot(x=args[0],**kwargs)

facetg = sns.FacetGrid(data=tips,row='sex',col='smoker',hue='time',legend_out=True) # 图例不显示,不明白为什么
facetg.map(custom_fn,'day') 
plt.legend() # 设置图例



## sns.catplot = FacetGrid(构建结构化多绘图网格)+stripplot
sns.catplot(data=tips,x='day',y='total_bill',col='sex')

13

2.3 连续性变量分析
2.3.1 单变量与双变量分布(histplot、kdeplot)
fig = plt.figure(figsize=(12,8))
fig.subplots_adjust(hspace=0.5) # 调整子图间距

## 单变量分布图
# sns.histplot  
plt.subplot(221)
sns.histplot(iris['sepal width (cm)'],kde=True)
plt.title('sns.histplot')


# sns.kdeplot  核密度分布图
plt.subplot(222)
sns.kdeplot(iris['sepal width (cm)'])
plt.title('sns.kdeplot')


## 双变量分布
plt.subplot(223)
# 两个变量分别显示核密度分布
sns.kdeplot(data=iris[['sepal length (cm)','sepal width (cm)']],fill=True,palette=sns.color_palette(palette='magma',n_colors=2)) 
plt.title('sns.kdeplot')

plt.subplot(224)
sns.kdeplot(x=iris['sepal length (cm)'],y=iris['sepal width (cm)'],fill=True) # 两变量组合分布
plt.title('sns.kdeplot')

14

2.3.2 双变量联合分布(joinplot)
## 双变量联合分布
# sns.joinplot 图像主体为两变量散点图,上右子图为单变量分布图
h2 = sns.jointplot(x=iris['sepal length (cm)'],y=iris['sepal width (cm)'])
# h1.set_axis_labels('index','value')

15

2.3.3 各变量交叉关系(pairplot 、PairGrid)
## 各变量交叉关系
# 第一种绘图方式
sns.pairplot(data=iris.iloc[:,0:3])  

# 第二种绘图方式
h1 = sns.PairGrid(data=iris.iloc[:,0:3])  # 在seaborn 可供用户使用的类一共三个 PairGrid,JointGrid,FacetGrid
# 对角线
h1.map_diag(sns.histplot)
# 下三角
h1.map_lower(sns.scatterplot) 
# 上三角
h1.map_upper(sns.kdeplot,fill=True)

1617

2.3.4 关系型图表(scatterplot、lineplot、regplot、residplot)
fig = plt.figure(figsize=(12,8))
fig.subplots_adjust(hspace=0.5) # 调整子图间距


# sns.scatterplot 散点图  
plt.subplot(221)
sns.scatterplot(data=iris,x='sepal length (cm)',y='sepal width (cm)',hue='target',palette=sns.color_palette('dark',3),style='target',markers=['*','$♠$','$♣$'])
plt.title('sns.scatterplot')

# sns.lineplot 折线图 
plt.subplot(222)
sns.lineplot(data=iris,x='sepal length (cm)',y='sepal width (cm)',hue='target')
plt.title('sns.lineplot')

# sns.regplot 回归分析
plt.subplot(223)
sns.regplot(data=iris,x='sepal length (cm)',y='sepal width (cm)',logistic=False)
plt.title('sns.regplot')

# sns.residplot  线性拟合后的残差分布图
plt.subplot(224)
sns.residplot(data=iris,x='sepal length (cm)',y='sepal width (cm)')
plt.title('sns.residplot')

18

2.4 矩阵图(heatmap、clustermap)
# 热力图(iris.corr()计算各列之间相关系数默认皮尔逊系数)
sns.heatmap(iris.corr(),cmap='Reds',annot=True)

19

# 各样本间进行聚类
sns.clustermap(iris,col_cluster=False)

20

三、matplotlib 绘图总结图解

matplotlib 官网详细总结

21

22

23

24

25

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值