はじめに
matplotlibのmplot3dの3Dボクセルグラフで立体的なハートを表示する。
コード
ハート
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%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()

回転アニメーション
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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())
解説
モジュールのインポート
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
データの生成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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とすることでハートの部分だけボクセルを表示することができる。
ハートの表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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()
アニメーションの表示
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 のグラフの回転アニメーション
参考

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 ...
コメント