Processing math: 100%

[matplotlib 3D] 32. voxelグラフでハートを表示して回転する

matplotlib 3D

はじめに

matplotlibのmplot3dの3Dボクセルグラフで立体的なハートを表示する。

コード

ハート

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
def midpoints(x):
sl = ()
for i in range(x.ndim):
x = (x[sl + np.index_exp[:-1]] + x[sl + np.index_exp[1:]]) / 2.0
sl += np.index_exp[:]
return x
# prepare some coordinates
n = 40
xr = np.linspace(-1.3,1.3,n)
yr = np.linspace(-1.3,1.3,n)
zr = np.linspace(-1.3,1.3,n)
xr, yr, zr = np.meshgrid(xr, yr, zr)
x = midpoints(xr)
y = midpoints(yr)
z = midpoints(zr)
# define a heart
heart = (x**2+(9/4)*y**2+z**2-1)**3-x**2*z**3-(9/80)*y**2*z**3 < 0
#plot
fig = plt.figure(figsize=(6,6))
ax = fig.gca(projection='3d')
ax.voxels(xr, yr, zr, heart, facecolor="r",edgecolors='w',linewidth=0.2)
#ax.set_aspect('equal')
plt.savefig("3Dvoxel_heart.png", dpi=100,transparent = False)
plt.show()

回転アニメーション

from IPython.display import HTML
import matplotlib.animation as animation
fig = plt.figure(figsize=(6,6))
ax = fig.gca(projection='3d')
ax.grid(False)
ax.set_axis_off()
def init():
ax.voxels(xr, yr, zr, heart, facecolor="r",edgecolors='pink',linewidth=0.2)
return fig,
def animate(i):
ax.view_init(elev=30., azim=3.6*i)
return fig,
# Animate
ani = animation.FuncAnimation(fig, animate, init_func=init,
frames=10, interval=100, blit=False)
HTML(ani.to_html5_video())

解説

モジュールのインポート

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

データの生成

def midpoints(x):
sl = ()
for i in range(x.ndim):
x = (x[sl + np.index_exp[:-1]] + x[sl + np.index_exp[1:]]) / 2.0
sl += np.index_exp[:]
return x
# prepare some coordinates
n = 40
xr = np.linspace(-1.3,1.3,n)
yr = np.linspace(-1.3,1.3,n)
zr = np.linspace(-1.3,1.3,n)
xr, yr, zr = np.meshgrid(xr, yr, zr)
x = midpoints(xr)
y = midpoints(yr)
z = midpoints(zr)
# define a heart
heart = (x**2+(9/4)*y**2+z**2-1)**3-x**2*z**3-(9/80)*y**2*z**3 < 0

データの生成については、下記のトーラスと同様にして生成した。

[matplotlib 3D] 31. voxels_torus
matplotlib mplot3dのvoxelでトーラスを表示。

heartの3D形状は以下の式で表される。[1]

(x^2 + \frac{4}{9}y^2+z^2-1)^3 -x^2z^3+ -\frac{9}{80}y^2z^3 = 0

<0とすることでハートの部分だけボクセルを表示することができる。

ハートの表示

#plot
fig = plt.figure(figsize=(6,6))
ax = fig.gca(projection='3d')
ax.voxels(xr, yr, zr, heart, facecolor="r",edgecolors='w',linewidth=0.2)
#ax.set_aspect('equal')
plt.savefig("3Dvoxel_heart.png", dpi=100,transparent = False)
plt.show()

アニメーションの表示

from IPython.display import HTML
import matplotlib.animation as animation
fig = plt.figure(figsize=(6,6))
ax = fig.gca(projection='3d')
ax.grid(False)
ax.set_axis_off()
def init():
ax.voxels(xr, yr, zr, heart, facecolor="r",edgecolors='pink',linewidth=0.2)
return fig,
def animate(i):
ax.view_init(elev=30., azim=3.6*i)
return fig,
# Animate
ani = animation.FuncAnimation(fig, animate, init_func=init,
frames=10, interval=100, blit=False)
HTML(ani.to_html5_video())

アニメーションのコードは下記のwireframeの回転アニメーションとおなじコードとなっている。

[matplotlib 3D] 14. 3Dグラフの回転アニメーション
matplotlib mplot3d のグラフの回転アニメーション
コードをダウンロード(.pyファイル)

コードをダウンロード(.ipynbファイル)

参考

Heart Surface -- from Wolfram MathWorld
A heart-shaped surface given by the sextic equation (x^2+9/4y^2+z^2-1)^3-x^2z^3-9/(80)y^2z^3=0 (Taubin 1993, 1994). The ...

コメント