よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

matplotlibで三次元立体グラフを描くテスト

グラフ描画用のPythonモジュールmatplotlibで三次元の立体的なグラフの描き方を学ぶ。写経とも言われる。
説明等は無し。



実行環境


Androidスマホ
termux
Python3.8
JupyterNotebook

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

↓ 三次元目の座標を生成するための関数

def func1(x, y):
    return x**2 + y**2
  • 3次元で描写するには2次元メッシュが必要

  • 2次元配列をarangeを用いて作る

  • x, y をそれぞれ1次元領域で分割する
x = np.arange(-3.0, 3.0, 0.1)
y = np.arange(-3.0, 3.0, 0.1)
x.shape , y.shape
((60,), (60,))
# 参考
t = np.arange(1, 2, 0.1)
t
array([1. , 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9])

2次元メッシュはmeshgridでつくる
Xの行にxの行列を,Yは列にyの配列を入れたものになっている

# 座標に変換
X, Y = np.meshgrid(x, y)
Z = func1(X, Y)
X, X.shape, X.ndim, type(X)
(array([[-3. , -2.9, -2.8, ...,  2.7,  2.8,  2.9],
        [-3. , -2.9, -2.8, ...,  2.7,  2.8,  2.9],
        [-3. , -2.9, -2.8, ...,  2.7,  2.8,  2.9],
        ...,
        [-3. , -2.9, -2.8, ...,  2.7,  2.8,  2.9],
        [-3. , -2.9, -2.8, ...,  2.7,  2.8,  2.9],
        [-3. , -2.9, -2.8, ...,  2.7,  2.8,  2.9]]),
 (60, 60),
 2,
 numpy.ndarray)

figureで2次元の図を生成する
その後,Axes3D関数で3次元にする

fig = plt.figure()
ax = Axes3D(fig)

ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("f(x, y)")

ax.plot_wireframe(X, Y, Z)

plt.savefig("3d.png")
plt.show()

f:id:chayarokurokuro:20200121134028p:plain



重要機密文書の処理


上の画像を処理して保存するまで(保存するんかいww

import numpy as np
import matplotlib.pyplot as plt 
from PIL import Image

# 上の三次元グラフ
file = "3d.png"
#Pillowで開きNumpy配列化
im = np.array(Image.open(file))
#確認
#print(im.shape , type(im), im.size)

# 色チャンネルをシャッフル
n = [0,1,2,3]
np.random.shuffle(n)
## シャッフル色の格納
im = im[: ,: ,n]


# 行を等分割してシャッフルしたインデックスを作成
g = np.arange(im.shape[0])
g = np.array_split(g, 48)
np.random.shuffle(g)
g = np.array(g).ravel()
#print(type(g))
#print(g)
## シャッフル行のインデックス格納
im = im[g, :,:]

# Pillowで保存
idata = Image.fromarray(im)
idata.save("3d_change.png")

おまけ
termuxで画像を開くコマンド(別のアプリが起動)

!termux-open 3d_change.png

f:id:chayarokurokuro:20200121134056p:plain



参考