背景介绍
大家好。之前给大家分享关于pandas的实战教程、python可视化教程,干货满满:
如果你想要系统和深入地了解学习pandas的语法和python可视化技巧,可以查看上面的文章。如果对你有帮助,还请关注下面公众号点赞关注转发~
大家好。之前给大家分享多篇关于python可视化技巧,今天给大家分享matplotlib库的基础教程,附带详细的代码和可视化结果,总结7种常见创建fig,ax的方法、5种绘制图中图、坐标轴各种配置总结、子图间距调整、子图关联等多种可视化技巧、新人小白也可以快速上手,干货满满。下面进入今天的主题~ 本文涉及的python库版本信息如下:
# !pip install mpl_font==1.1.0
# !pip install mplcyberpunk==0.7.1
import pandas as pd
from matplotlib import pyplot as plt
import mpl_font.noto
import numpy as np
import os
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as tick
import seaborn as sns
import warnings
warnings.filterwarnings("ignore") # 完全屏蔽所有警告
%matplotlib inline
print("matplotlib: ",mpl.__version__ ) # matplotlib: 3.7.5
print("pandas: ",pd.__version__) # matplotlib: 3.7.5
print("seaborn: ",sns.__version__) # seaborn: 0.11.0
本文目录
创建画布fig和子图对象ax的方法汇总
什么是fig,axes,ax,plt,axis?
如下图所示;
整个图可以得到下面:
- fig: 整个画布;
- axes:画图ax的汇总;上图分别为axes[0],axes[1]。
- ax: 子图ax(为画布fig中一个特定区域)
- axis:具体的坐标轴;
- plt: Pyplot为底层面向对象的绘图库提供状态机接口。状态机隐式自动创建图形和轴,以实现所需的绘图。
下面将给大家介绍在matplotlib库中常见总结fig,ax的方法函数。
方法1: 使用fig.add_axes创建fig和ax
# 定义fig
fig= plt.figure(figsize=(6,6), dpi=100)
# 自定义画布ax
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 散点图位置
ax2 = fig.add_axes([0.1, 0.96, 0.8, 0.1]) # 边际分布图位置
ax3 = fig.add_axes([0.96, 0.1, 0.1, 0.8]) # 边际分布图位置
plt.show()
方法2: 使用fig.add_subplot 创建fig和ax
# 定义fig
fig= plt.figure(figsize=(8,6), dpi=200)
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)
方法3: 使用plt.subplot2grid 创建fig和ax
# 绘制不规则的网格ax(空间布局)
ax = plt.subplot2grid((2,3),(0,0),rowspan=1, colspan=1)
ax = plt.subplot2grid((2,3),(1,0),rowspan=1, colspan=1,projection='polar')
ax = plt.subplot2grid((2,3),(0,1),rowspan=1, colspan=2) # 使用一行2列的位置区间画图
fig = ax.get_figure()
方法4: 使用plt.subplots 创建fig和ax
fig, axes = plt.subplots(2,2)
ax1= axes[0,0] #第一个位置的画布
ax2= axes[1,1] #第4个位置的画布
方法5: 使用plt.subplot 创建fig和ax
ax= plt.subplot(221)
ax= plt.subplot(222)
fig= plt.gcf()
方法6 : 使用plt.add_subplot 创建fig和ax
from matplotlib.gridspec import GridSpec
fig = plt.figure()
gs = GridSpec(1, 3)
ax = fig.add_subplot(gs[0, 0])
ax.set_title("grid1")
ax = fig.add_subplot(gs[0, 1:])
ax.set_title("grid2")
plt.show()
方法7 : 使用plt.subplot_mosaic 创建fig和ax
fig, axes = plt.subplot_mosaic([['upleft', 'right'],
['lowleft', 'right']], layout='constrained')
axes['upleft'].set_title('upleft')
axes['lowleft'].set_title('lowleft')
axes['right'].set_title('right')
#通过ax获得fig
fig =ax.get_figure()
# 关闭fig
plt.close(fig)
绘制图中图方法总结
这里给大家总结如何在子图中绘制子图。
绘制放大图方法1: 使用mpl_toolkits的zoomed_inset_axes
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
# 生成一些数据
x = np.linspace(0, 10, 1000)
y = np.sin(x)
# 创建主图
fig, ax = plt.subplots(figsize=(8, 6))
# 绘制主图数据
ax.plot(x, y, label='Main Plot')
# 创建并配置放大图
axins = zoomed_inset_axes(ax, 1.5, loc='lower left',
bbox_to_anchor=(0.4, 0.8,1, .5), # 锚点位置(x,y,width, height)相对图的相对位置
bbox_transform=ax.transAxes,
) # 放大倍数为6倍,位置在右上角
axins.plot(x, y,c='r') # 在放大图上再次绘制数据
# 设置放大图的x和y轴范围
x1, x2, y1, y2 = 2.5, 3, 0.3, 0.5 # 指定局部放大区域
axins.set_xlim(x1, x2)
axins.set_ylim(y1, y2)
# 移除放大图的顶部和右侧边框
axins.spines['top'].set_visible(False)
axins.spines['right'].set_visible(False)
# axins.xaxis.set_ticks_position('bottom')
# axins.yaxis.set_ticks_position('left')
# 标记主图和放大图之间的关联
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5")
# 显示图形
plt.show()
绘制放大图方法2:使用ax.indicate_inset_zoom绘制放大图
fig,ax = plt.subplots(figsize=(6,6))
ax.set_xlim(5, 10)
ax.set_ylim(0, 10)
ax1 = [6, 5, 3, 2] #表示从ax2子图横坐标为6,纵坐标为5地方插入子图,宽度为3,高度为2
x1, x2, y1, y2 = 5.5,6.6, 2, 4
axins = ax.inset_axes(
[0.5, 0.5, 0.4, 0.4],
xlim=(x1, x2), ylim=(y1, y2))
axins.set_facecolor('r')
ax.indicate_inset_zoom(axins, edgecolor="black")
axins.set_title("axins")
print(fig.axes, axins)
plt.show()
绘制图中图方法1:使用mpl_toolkits的inset_axes绘制放大图
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
fig = plt.figure(figsize=[7.5, 3.8])
ax = fig.add_subplot(121)
axins = inset_axes(ax,
width="100%", #axins 显示宽度比例
height="100%",#axins 显示高度比例
bbox_to_anchor=(.2, .4, .6, .5), # 锚点位置(x,y,width, height)
bbox_transform=ax.transAxes,
loc='lower left' #显示的方向
)
# For visualization purposes we mark the bounding box by a rectangle
ax.add_patch(plt.Rectangle((.2, .4), .65, .55, ls="--", ec="c", fc="None",
transform=ax.transAxes))
ax.set(xlim=(0, 10), ylim=(0, 10))
绘制图中图方法2:使用ax.inset_axes绘制放大图
fig,ax = plt.subplots(figsize=(6,6))
ax.set_xlim(5, 10)
ax.set_ylim(0, 10)
coord = [6, 5, 3, 2] #表示从ax2子图横坐标为6,纵坐标为5地方插入子图,宽度为3,高度为2
axines = ax.inset_axes(coord, transform = ax.transData) #因为是依据坐标刻度插入,使用的是ax2坐标刻度
axines.set_title("axines")
plt.show()
绘制图中图方法3:使用fig.add_axes来重叠法展示图中图
import matplotlib.pyplot as plt
import numpy as np
# 主图的数据
x = np.linspace(0, 2*np.pi, 100)
y1 = np.sin(x)
# 创建主图
fig, ax = plt.subplots()
# 在主图上绘制数据
ax.plot(x, y1, label='Main Plot')
ax.legend(loc='lower left')
# 设置图中图的位置和大小
# 这里以左下角坐标(0.55, 0.65),宽高比为0.3和0.2为例
inset_ax = fig.add_axes([0.55, 0.65, 0.3, 0.2], facecolor='none')
# 图中图的数据
y2 = np.cos(x)
# 在图中图上绘制数据
inset_ax.plot(x, y2, 'r', label='Inset Plot')
inset_ax.legend(loc='lower left')
# 可选地,可以调整图中图的坐标刻度、标签等
inset_ax.set_xlim([0, np.pi])
inset_ax.set_ylim([-1, 1])
inset_ax.set_xlabel('X Label in Inset')
inset_ax.set_ylabel('Y Label in Inset')
# 显示图形
plt.show()
子图ax坐标轴相关配置方法汇总
这里给大家介绍子图ax相关坐标轴显示配置
隐藏指定坐标轴&&刻度
from matplotlib.ticker import MultipleLocator,FormatStrFormatter
params = {"legend.fontsize": 8,"legend.frameon":False, 'xtick.direction':'in', 'ytick.direction':'in'} # 设置图例大小,是否透明,坐标轴朝向in朝内,out朝外。
with plt.rc_context(params):
fig,ax= plt.subplots(figsize=(6,4))
ax.set_xlabel('x [m]')
# 隐藏指定坐标轴
ax.spines["top"].set_visible(False) # top,right,left,bottom
ax.spines["right"].set_visible(False)
设置坐标轴朝向外面
from matplotlib.ticker import MultipleLocator,FormatStrFormatter
params = {"legend.fontsize": 8,"legend.frameon":False, 'xtick.direction':'in', 'ytick.direction':'in'}
with plt.rc_context(params):
fig,ax= plt.subplots(figsize=(6,4))
ax.set_xlabel('x [m]')
ax.spines["top"].set_visible(False) # top,right,left,bottom
ax.spines["right"].set_visible(False)
# 坐标轴朝向in朝内,out朝外,同时设置x轴和y轴的刻度方向
ax.tick_params(direction='out', axis='both')
隐藏坐标轴但是显示刻度
from matplotlib.ticker import MultipleLocator,FormatStrFormatter
params = {"legend.fontsize": 8,"legend.frameon":False, 'xtick.direction':'in', 'ytick.direction':'in'}
with plt.rc_context(params):
fig,ax= plt.subplots(figsize=(6,4))
ax.set_xlabel('x [m]')
ax.spines["top"].set_visible(False) # top,right,left,bottom
ax.spines["right"].set_visible(False)
ax.tick_params(direction='out', axis='both') # 同时设置x轴和y轴的刻度方向
ax.spines["left"].set_visible(False) # top,right,left,bottom
ax.axes.yaxis.set_visible(True)# 设置坐标轴刻度是否可见 xaxis, yaxis
将坐标轴显示在上面和右边
from matplotlib.ticker import MultipleLocator,FormatStrFormatter
params = {"legend.fontsize": 8,"legend.frameon":False, 'xtick.direction':'in', 'ytick.direction':'in'}
with plt.rc_context(params):
fig,ax= plt.subplots(figsize=(6,4))
ax.set_xlabel('x [m]')
ax.spines["top"].set_visible(True) # top,right,left,bottom
ax.spines["right"].set_visible(True)
ax.tick_params(direction='out', axis='both') # 同时设置x轴和y轴的刻度方向
ax.spines["left"].set_visible(False) # top,right,left,bottom
ax.spines["bottom"].set_visible(False) # top,right,left,bottom
ax.axes.yaxis.set_visible(True)# 设置坐标轴刻度是否可见 xaxis, yaxis
ax.axes.xaxis.tick_top()# 让x轴平移到上边
ax.axes.yaxis.tick_right()#让y轴平移到右边
ax.axes.yaxis.set_label_position('right') #设置y轴的标签到右边显示
ax.axes.xaxis.set_label_position('top') #设置y轴的标签到右边显示
ax.set_xlabel('x轴')
ax.set_ylabel('y轴')
坐标轴逆序展示&&修改坐标轴标签
from matplotlib.ticker import MultipleLocator,FormatStrFormatter
params = {"legend.fontsize": 8,"legend.frameon":False, 'xtick.direction':'in', 'ytick.direction':'in'}
with plt.rc_context(params):
fig,ax= plt.subplots(figsize=(6,4))
ax.set_xlabel('x [m]')
ax.set_xlim(1,20) #设置坐标轴范围(1,100)
ax.set_ylim(1,20) #设置坐标轴范围(1,100)
ax.invert_yaxis() # 将y坐标轴进行逆序
ticks = ax.set_xticks([1,6,9,13,20]) # 设置刻度
labels = ax.set_xticklabels(['one','two','three','four','five'],ha='right',rotation = 30,fontsize = 'small') # 设置刻度标签
设置坐标轴的主刻度和副刻度
from matplotlib.ticker import MultipleLocator,FormatStrFormatter
params = {"legend.fontsize": 8,"legend.frameon":False, 'xtick.direction':'in', 'ytick.direction':'in'}
with plt.rc_context(params):
fig,ax= plt.subplots(figsize=(10,4))
ax.set_xlabel('x [m]')
ax.set_xlim(1,20) #设置坐标轴范围(1,100)
ax.set_ylim(1,20) #设置坐标轴范围(1,100)
ax.xaxis.set_major_locator( MultipleLocator(2)) # 设置x轴主刻度的比例
ax.xaxis.set_minor_locator(MultipleLocator(1)) # 设置x轴副刻度的比例
ax.xaxis.set_minor_formatter(FormatStrFormatter('%0.2f')) # 设置x轴副刻度的展示格式
ax.yaxis.set_major_locator( MultipleLocator(4)) # 设置x轴主刻度的比例
ax.tick_params(which='major', length=12) # 设置主刻度的长度
ax.tick_params(which='minor', length=4) # 设置副刻度的长度
一个图总结所有的配置
from matplotlib.ticker import MultipleLocator,FormatStrFormatter
params = {"legend.fontsize": 8,"legend.frameon":False, 'xtick.direction':'in', 'ytick.direction':'in'}
with plt.rc_context(params):
fig = plt.figure(layout='constrained', figsize=(10,4))
fig.suptitle('这里是图标题')
axes = fig.subplots(1,2)
axes[0].set_xlabel('x [m]')
# axes[0].spines["top"].set_visible(False) # top,right,left,bottom
axes[0].spines["right"].set_visible(False)
axes[0].spines["left"].set_visible(False)
axes[0].spines["bottom"].set_visible(False)
axes[0].tick_params(direction='out', axis='both') # 同时设置x轴和y轴的刻度方向
axes[0].axes.yaxis.set_visible(True)# 设置坐标轴刻度是否可见 xaxis, yaxis
axes[0].axes.xaxis.tick_top()# 让x轴平移到上边
axes[0].axes.yaxis.tick_right()#让y轴平移到右边
axes[0].axes.yaxis.set_label_position('right') #设置y轴的标签到右边显示
axes[0].axes.xaxis.set_label_position('top') #设置y轴的标签到右边显示
axes[0].set_ylabel('可见刻度值')
axes[0].set_title('子图1')
axes[1].set_facecolor('red')
axes[1].set_title('子图2')
axes[1].set_xlabel('x轴')
axes[1].set_ylabel('y轴')
axes[1].invert_yaxis() # 将y坐标轴进行逆序
axes[1].set_xlim(1,20) #设置坐标轴范围(1,100)
axes[1].set_ylim(1,20) #设置坐标轴范围(1,100)
ticks = axes[1].set_xticks([1,2,4,7,10]) # 设置刻度
labels = axes[1].set_xticklabels(['one','two','three','four','five'],ha='right',rotation = 30,fontsize = 'small') # 设置刻度标签
axes[1].xaxis.set_major_locator( MultipleLocator(2)) # 设置x轴主刻度的比例
axes[1].xaxis.set_minor_locator(MultipleLocator(1)) # 设置x轴副刻度的比例
axes[1].xaxis.set_minor_formatter(FormatStrFormatter('%0.2f')) # 设置x轴副刻度的展示格式
axes[1].yaxis.set_major_locator( MultipleLocator(4)) # 设置x轴主刻度的比例
axes[1].tick_params(which='major', length=12) # 设置主刻度的长度
axes[1].tick_params(which='minor', length=4) # 设置副刻度的长度
综合应用展示
这里给大家分享
调节子图之间空间布局间距
plt.subplots_adjust()
fig.tight_layout()
fig= plt.figure(figsize=(8,6), dpi=200)
fig.subplots_adjust(left=0.1,
wspace=0.06,
hspace=0.16)
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)
效果展示:
子图之间添加备注
import numpy as np
import mpl_font.noto
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize = (14, 6))
axes[0].set_title("图A",fontsize = 20)#设置子图标题
#下面绘制子图2,绘制一个堆积柱状图
axes[1].set_title("图B",fontsize = 20)
#定义注释文本的样式
bbox_args = dict(boxstyle="round", fc="lightgreen")
#定义注释箭头的样式
arrow_args = dict(arrowstyle="<->",color='r')
#先把终点画在子图A上面
axes[0].annotate("终点", xy=(0.2, 0.5), xytext=(0.2, 0.5), ha="center", va="center", bbox=bbox_args, )
#把起点画在子图B上面,并设置跨图注释起点
axes[1].annotate("起点",
xy=(0.2, 0.5), xycoords=axes[0].transData,#跨子图设置,这里的意思是把xy的坐标转换为axes[0,0]的坐标
xytext=(1.8, 0.5),#开始点坐标这里(1.8, 0.5)就是以子图1坐标系下的坐标
ha="left", va="bottom",
bbox=bbox_args,
arrowprops=dict(connectionstyle="arc3,rad=0.2",
linewidth=2, # 箭头线宽
linestyle='--', # 箭头线型
facecolor='black', # 箭头填充颜色
edgecolor='black', # 箭头边缘颜色
alpha=0.2, # 透明度
**arrow_args,
))
plt.show()
子图之间fig,ax,plt转换
axes = fig.axes
fig=ax.get_figure()
fig =plt.gcf()
ax= plt.gca()
设置fig和ax的背景颜色
fig = plt.figure(layout='constrained', facecolor='lightskyblue',figsize=(10,4))
fig.suptitle('here is Figure title')
figL, figR = fig.subfigures(1, 2)
figL.set_facecolor('thistle')
axLes = figL.subplots(1,2)
axLes[1].set_xlabel('x [m]')
axLes[0].set_facecolor('red')
figL.suptitle('Left subfigure title')
figR.set_facecolor('paleturquoise')
axR = figR.subplots(1, 2, sharey=True)
axR[0].set_title('Axes 1')
figR.suptitle('Right subfigure title')
保存图片为png,svg,pdf
fig.savefig("demo.png",dpi=300)
fig.savefig("demo.pdf")
fig.savefig("demo.svg")
plt.colse(fig)
将svg图片转换为png,jpg图片
# !pip install cairosvg==2.7.1
import cairosvg
from PIL import Image
cairosvg.svg2png(url="demo.svg", write_to="svg2jpg.jpg", dpi=600)
img = Image.open("svg2jpg.jpg")
img
参考文档
z先生说
今天给大家分享,