1. 程式人生 > >聰哥哥教你學Python之3D畫圖

聰哥哥教你學Python之3D畫圖

看著那些高大尚的表格、線形圖或者是遊戲中的統計分析圖等等。如果是用Java這門後端語言來實現,實現倒不是很大的問題,不過需要一定的精力和時間投入。但是那樣代價太大了。

今天我主要介紹的是Python的3D畫圖API,以下是程式碼示例:

示例一:

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

mpl.rcParams['legend.fontsize'] = 20  # mpl模組載入的時候載入配置資訊儲存在rcParams變數中,rc_params_from_file()函式從檔案載入配置資訊

font = {
    'color': 'b',
    'style': 'oblique',
    'size': 20,
    'weight': 'bold'
}
fig = plt.figure(figsize=(16, 12))  #引數為圖片大小
ax = fig.gca(projection='3d')  # get current axes,且座標軸是3d的

# 準備資料
theta = np.linspace(-8 * np.pi, 8 * np.pi, 100)  # 生成等差數列,[-8π,8π],個數為100
z = np.linspace(-2, 2, 100)  # [-2,2]容量為100的等差數列,這裡的數量必須與theta保持一致,因為下面要做對應元素的運算
r = z ** 2 + 1
x = r * np.sin(theta)  # [-5,5]
y = r * np.cos(theta)  # [-5,5]
ax.set_xlabel("X", fontdict=font)
ax.set_ylabel("Y", fontdict=font)
ax.set_zlabel("Z", fontdict=font)
ax.set_title("Line Plot", alpha=0.5, fontdict=font) #alpha引數指透明度transparent
ax.plot(x, y, z, label='parametric curve')
ax.legend(loc='upper right') #legend的位置可選:upper right/left/center,lower right/left/center,right,left,center,best等等

plt.show()

執行後的結果是:

示例二:

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

label_font = {
    'color': 'c',
    'size': 15,
    'weight': 'bold'
}


def randrange(n, vmin, vmax):
    r = np.random.rand(n)  # 隨機生成n個介於0~1之間的數
    return (vmax - vmin) * r + vmin  # 得到n個[vmin,vmax]之間的隨機數


fig = plt.figure(figsize=(16, 12))
ax = fig.add_subplot(111, projection="3d")  # 新增子座標軸,111表示1行1列的第一個子圖
n = 200
for zlow, zhigh, c, m, l in [(4, 15, 'r', 'o', 'positive'),
                             (13, 40, 'g', '*', 'negative')]:  # 用兩個tuple,是為了將形狀和顏色區別開來
    x = randrange(n, 15, 40)
    y = randrange(n, -5, 25)
    z = randrange(n, zlow, zhigh)
    ax.scatter(x, y, z, c=c, marker=m, label=l, s=z * 10) #這裡marker的尺寸和z的大小成正比

ax.set_xlabel("X axis", fontdict=label_font)
ax.set_ylabel("Y axis", fontdict=label_font)
ax.set_zlabel("Z axis", fontdict=label_font)
ax.set_title("Scatter plot", alpha=0.6, color="b", size=25, weight='bold', backgroundcolor="y")   #子圖的title
ax.legend(loc="upper left")    #legend的位置左上

plt.show()

執行後結果如圖:

示例三:

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter

fig = plt.figure(figsize=(16,12))
ax = fig.gca(projection="3d")

# 準備資料
x = np.arange(-5, 5, 0.25)    #生成[-5,5]間隔0.25的數列,間隔越小,曲面越平滑
y = np.arange(-5, 5, 0.25)
x, y = np.meshgrid(x,y)  #格點矩陣,原來的x行向量向下複製len(y)次,形成len(y)*len(x)的矩陣,即為新的x矩陣;原來的y列向量向右複製len(x)次,形成len(y)*len(x)的矩陣,即為新的y矩陣;新的x矩陣和新的y矩陣shape相同
r = np.sqrt(x ** 2 + y ** 2)
z = np.sin(r)

surf = ax.plot_surface(x, y, z, cmap=cm.coolwarm)  # cmap指color map

# 自定義z軸
ax.set_zlim(-1, 1)
ax.zaxis.set_major_locator(LinearLocator(20))  # z軸網格線的疏密,刻度的疏密,20表示刻度的個數
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))  # 將z的value字串轉為float,保留2位小數

#設定座標軸的label和標題
ax.set_xlabel('x',size=15)
ax.set_ylabel('y',size=15)
ax.set_zlabel('z',size=15)
ax.set_title("Surface plot", weight='bold', size=20)

#新增右側的色卡條
fig.colorbar(surf, shrink=0.6, aspect=8)  # shrink表示整體收縮比例,aspect僅對bar的寬度有影響,aspect值越大,bar越窄
plt.show()

執行後的結果如圖: