matplotlib---8.3D绘图
一、直线、散点图、插值
1.3D绘图与2D绘图区别
3D绘图与2D绘图的调用方法几乎相同,除了增加一个 projection='3d'的关键字参数。
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig=plt.figure() ax=fig.add_subplot(111,projection='3d') # 旧式写法 ax=Axes3D(fig) #新式写法

2.插值画3D图
(1)载入数据
# 载入模块
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import pandas as pd
import seaborn as sns
from scipy import interpolate
df_epsilon_alpha = pd.read_excel('实验记录_超参数.xlsx',sheet_name='epsilon_alpha')
#生成数据
epsilon = np.array(df_epsilon_alpha['epsilon'].values)
alpha = np.array(df_epsilon_alpha['alpha'].values)
Precision = np.array(df_epsilon_alpha['Precision'].values)
(2)将x和y扩充到想要的大小
xnew = np.arange(0.1, 1, 0.09) #左闭右闭每0.09间隔生成一个数 ynew = np.arange(0.1, 1, 0.09) 或者
x = np.linspace(0.1,0.9,9)#0.1到0.9生成9个数 y = np.linspace(0.1,0.9,9)
(3)对z插值
x,y原数据:
x = np.linspace(0.1,0.9,9) y = np.linspace(0.1,0.9,9)
z = Precision
采用 scipy.interpolate.interp2d函数进行插值
f = interpolate.interp2d(x, y, z, kind='cubic')
x,y扩充数据:
xnew = np.arange(0.1, 1, 0.03)#(31,) ynew = np.arange(0.1, 1, 0.03)#(31,) znew = f(xnew, ynew)#(31,31)
znew为插值后的z
(4)画图
采用 from mpl_toolkits.mplot3d import Axes3D进行画三维图
Axes3D简单用法:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d')
比如采用plot_trisurf画三维图:
plot_trisurf(x,y,z)
plot_trisurf对数据要求是:x.shape = y.shape = z.shape,所以x和y的shape需要修改,采用np.meshgrid,且都为一维数据
修改x,y,z输入画图函数前的shape
xx1, yy1 = np.meshgrid(xnew, ynew)#执行之后,xx1.shape=(31,31),yy1.shape=(31,31) newshape = (xx1.shape[0])*(xx1.shape[0]) y_input = xx1.reshape(newshape) x_input = yy1.reshape(newshape) z_input = znew.reshape(newshape)
x_input.shape,y_input.shape,z_input.shape=((961,), (961,), (961,))
#画图
sns.set(style='ticks')
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(x_input,y_input,z_input,cmap=cm.coolwarm)
plt.xlim((0.1,0.9))
plt.xticks([0.1,0.3,0.5,0.7,0.9])
plt.yticks([0.1,0.3,0.5,0.7,0.9])
ax.set_xlabel(r'$\alpha$',fontdict={'color': 'black',
'family': 'Times New Roman',
'weight': 'normal',
'size': 18})
ax.set_ylabel(r'$\epsilon$',fontdict={'color': 'black',
'family': 'Times New Roman',
'weight': 'normal',
'size': 18})
ax.set_zlabel('precision',fontdict={'color': 'black',
'family': 'Times New Roman',
'weight': 'normal',
'size': 18})
plt.tight_layout()
# plt.savefig('loc_svg/alpha_epsilon2.svg',dpi=600) #指定分辨率保存
plt.show()
| 插值前 | 插值后 |
![]() |
![]() |
3.绘制直线
Axes3D.plot(xs, ys, *args, **kwargs)
参数:
xs,ys:点的x,y坐标zs:点的z坐标。该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值zdir:指定那个是z轴。其值可以是'x'或者'y'或者'z'- 剩下的关键字参数与
Axes.plot()相同
4.绘制散点图
Axes3D.scatter(xs, ys, zs=0, zdir=’z’, s=20, c=’b’, depthshade=True, *args, **kwargs)
参数:
xs,ys:点的x,y坐标zs:点的z坐标。该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值zdir:指定那个是z轴。其值可以是'x'或者'y'或者'z's:散点的大小(单位为point^2).该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值c:散点的颜色。你可以将它设为一个颜色字符串,表示所有的点都是一个颜色。或者是个cmap,指定颜色图depthshade:一个布尔值。如果为True,则通过对marker设置阴影来展示层次关系- 剩下的关键字参数与
Axes.scatter()相同
5.绘制线框
Axes3D.plot_wireframe(X, Y, Z, *args, **kwargs)
参数:
X,Y:点的x,y坐标Z:点的z坐标。该值可以是一个标量(表示对所有点都取同一个值);也可以是个数组或列表,表示每个点一个值rstride:行的步长cstride:列的步长- 剩下的关键字传递给
LineCollection
二、修改X,Y,Z轴的刻度值
1.修改X,Y,Z轴的刻度值
from matplotlib.ticker import MultipleLocator,FuncFormatter
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib import colors
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
import matplotlib.ticker as ticker
def fun(x):
if x >= 1:
return 1
return x
def to_percent(temp, position):
return '%1.0f'%(100*temp)
x = np.arange(0, 0.5, 0.001)
y = np.arange(0, 0.05, 0.001)
x, y = np.meshgrid(x, y)
z = (3*x+y-x*x-np.sqrt(2*x*x*x-3*x*x*x*x+x*x+22*x*x*y-22*x*y-12*x*x*x*y-8*x*x*y*y+12*x*y*y-7*y*y))/(2*x+2*y)
for row in range(len(z)):
for col in range(len(z[0])):
z[row][col] = fun(z[row][col])
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_zlim3d(0.6,1.0)
ax.zaxis.set_major_locator(LinearLocator(5))#Z轴显示5个刻度值
norm = colors.Normalize(vmin=0.6,vmax=1.0)
ax.xaxis.set_major_formatter(FuncFormatter(to_percent))#将X,Y,Z轴的坐标轴放大100倍
ax.yaxis.set_major_formatter(FuncFormatter(to_percent))
ax.zaxis.set_major_formatter(FuncFormatter(to_percent))
ax.set_xlabel(r'$\alpha$(%)')
ax.set_ylabel(r'$\theta$(%)')
ax.set_zlabel(r'$\gamma^{*}$(%)')#坐标轴
surf = ax.plot_surface(x, y, z,
cmap=cm.coolwarm,
linewidth=0,
norm=norm,
antialiased=False,
edgecolor='none')
ax.contourf(x,y,z,zdir='z',offset=-2,cmap='rainbow')
修改colorbar的刻度为百分的形式
def fmt(x,pos):
print(x)
# a, b = '{:2.2e}'.format(x).split('e')
# b = int(b)
return r'${}$%'.format(int(x*100))
cbar = plt.colorbar(surf,shrink=0.5, aspect=5,format=ticker.FuncFormatter(fmt))#format用来修改调色板的刻度值
cbar.set_ticks([.6,.7,.8,.9,1.0]) plt.tight_layout()
plt.savefig('实验图.svg',dpi=600) #指定分辨率保存
plt.show()
| 未修改前 | 修改后 |
![]() |
![]() |
|
alpha:0.0-0.5 theta:0.00-0.05 gamma:0.60-1.00 colorbar:0.60-1.00 |
alpha:0:50(每个乘以100) theta:0-5(每个乘以100) gamma:60-100(每个乘以100) colorbar:60%-100%(每个乘以100) |
参考文献:




浙公网安备 33010602011771号