一、直線、散點圖、插值
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) |
參考文獻: