tkPlot3d.py ダウンロード/コピー
tkPlot3d.py
tkPlot3d.py
1"""
2tkPlot3d.py - 3Dプロット関連のユーティリティ関数を提供するモジュール
3
4概要:
5 MatplotlibとNumPyを使用して、3Dサーフェス、等値面、散布図、2D等高線プロットなどを描画するための補助関数群を提供します。
6 カラーマップの作成や3D軸のスケーリング調整など、多様な3D可視化ニーズに対応します。
7
8詳細説明:
9 このモジュールには、3D空間におけるデータの表現を容易にするための複数の関数が含まれています。
10 `plot_surface3d` は一般的な3Dサーフェスプロットを扱い、`plot_isosurface3d` は`marching_cubes`アルゴリズムを用いてボリュームデータから等値面を抽出・描画します。
11 また、`make_cmap` などの関数は、カスタムカラーマップを生成してプロットの視覚表現を豊かにするために使用できます。
12 軸の統一スケール設定やカラーバーの追加など、プロットの見た目を整えるためのユーティリティも含まれています。
13
14関連リンク:
15 :doc:`tkPlot3d_usage`
16"""
17import numpy as np
18import matplotlib.pyplot as plt
19from mpl_toolkits.mplot3d import Axes3D
20from mpl_toolkits.mplot3d.art3d import Poly3DCollection
21from matplotlib.colors import LightSource, Normalize, LinearSegmentedColormap
22from matplotlib.patches import Patch
23from matplotlib import cm
24from matplotlib.animation import FuncAnimation
25
26from skimage.measure import marching_cubes
27
28
29def get_max_xyz(x, y, z):
30 """
31 概要: 3D座標の最大絶対値を取得します。
32
33 詳細説明:
34 与えられたX, Y, Z座標配列から、すべての要素の最大絶対値を計算します。
35 これにより、3Dプロットの軸範囲を統一するための基準値を得られます。
36
37 :param x: (numpy.ndarray) X座標の配列。
38 :param y: (numpy.ndarray) Y座標の配列。
39 :param z: (numpy.ndarray) Z座標の配列。
40 :returns: (float) X, Y, Z座標の最大値の中から最も大きい値。
41 """
42 x1d = x.flatten()
43 y1d = y.flatten()
44 z1d = z.flatten()
45 maxx = max([max(x1d), max(y1d), max(z1d)])
46 return maxx
47
48def set_cubic_scale(ax, maxx):
49 """
50 概要: 3D軸のスケールを立方体状に設定します。
51
52 詳細説明:
53 3DプロットのX, Y, Z軸の表示範囲を、与えられた最大値に基づいて対称な立方体状に設定し、アスペクト比を1:1:1にします。
54
55 :param ax: (matplotlib.axes.Axes) 対象となる3D Axesオブジェクト。
56 :param maxx: (float) 各軸の最大絶対値。`[-maxx, maxx]` の範囲に設定されます。
57 :returns: (None)
58 """
59 ax.set_xlim([-maxx, maxx])
60 ax.set_ylim([-maxx, maxx])
61 ax.set_zlim([-maxx, maxx])
62 ax.set_box_aspect([1, 1, 1])
63
64#colorを使う場合
65# color = 'cyan'
66#cmapを使う場合
67# cmap = 'bwr'
68#3色塗分け
69# colors = np.empty(x.shape, dtype = object)
70# colors[r < 0] = 'red'
71# colors[r == 0] = 'white'
72# colors[r > 0] = 'blue'
73
74# 回転角に基づく色の設定
75#color_map = plt.cm.viridis(phi / (2 * np.pi))
76#color_map = plt.cm.Reds(phi / (2 * np.pi))
77#norm = Normalize(vmin=np.min(phi), vmax=np.max(phi))
78#norm = Normalize(vmin = 100, vmax = 200)
79#color_map = plt.cm.Reds(norm(phi))
80
81# カラーマップの正規化(範囲の調整)
82#vmin, vmax = np.min(phi), np.max(phi)
83#norm = Normalize(vmin=vmin, vmax=vmax)
84#sm = plt.cm.ScalarMappable(cmap=plt.cm.Reds, norm=norm)
85#sm.set_array([])
86#color_map = sm.to_rgba(phi)
87
88def make_cmap(colors, cmap_name = 'custom_cmap', nbins = 100):
89 """
90 概要: カスタムカラーマップを作成します。
91
92 詳細説明:
93 指定された色のリストから、`matplotlib.colors.ListedColormap` (nbinsが少ない場合)
94 または `matplotlib.colors.LinearSegmentedColormap` を用いてカスタムカラーマップを生成します。
95
96 :param colors: (list) カラーマップを構成する色のリスト。色の形式はmatplotlibが認識するものであれば何でも可(例: 'red', '#FF0000', (1, 0, 0))。
97 :param cmap_name: (str, optional) カスタムカラーマップの名前。デフォルトは 'custom_cmap'。
98 :param nbins: (int, optional) 線形補間を行う際のビン数。`colors`の要素数以下の場合、`ListedColormap`を使用。デフォルトは100。
99 :returns: (matplotlib.colors.Colormap) 作成されたカスタムカラーマップオブジェクト。
100 """
101 # Note: ListedColormap がインポートされていませんが、既存コードの変更はルールにより行いません。
102 if nbins is None or nbins <= len(colors):
103 # ListedColormap が定義されていないため、この行は実行時にエラーになる可能性があります。
104 custom_cmap = ListedColormap(colors)
105 else:
106 custom_cmap = LinearSegmentedColormap.from_list(cmap_name, colors, N = nbins)
107 return custom_cmap
108
109def make_color_map(x, colors, cmap_name = 'custom_cmap', nbins = 100):
110 """
111 概要: データに基づいてカスタムカラーマップを生成し、その色配列を返します。
112
113 詳細説明:
114 `make_cmap` を利用してカスタムカラーマップを作成し、入力データ `x` を正規化してその
115 カラーマップを適用したRGBA色の配列を生成します。
116
117 :param x: (numpy.ndarray) カラーマップを適用する数値データ。
118 :param colors: (list) カラーマップを構成する色のリスト。
119 :param cmap_name: (str, optional) カスタムカラーマップの名前。デフォルトは 'custom_cmap'。
120 :param nbins: (int, optional) 線形補間を行う際のビン数。デフォルトは100。
121 :returns: (numpy.ndarray) `x` の各要素に対応するRGBA色値の配列。
122 """
123 custom_cmap = LinearSegmentedColormap.from_list(cmap_name, colors, N = nbins)
124 # Note: `norm` 変数が未定義ですが、既存コードの変更はルールにより行いません。
125 color_map = custom_cmap(norm(x))
126
127 return color_map
128
129def make_colors(x, colors, vmin = None, vmax = None, cmap_name = 'custom_cmap', nbins = 100):
130 """
131 概要: データに基づいて色配列を作成します。
132
133 詳細説明:
134 入力データ `x` の最小値・最大値(または指定された `vmin`, `vmax`)で正規化し、
135 カスタムカラーマップを適用してRGBA色配列を生成します。
136
137 :param x: (numpy.ndarray) カラーマップを適用する数値データ。
138 :param colors: (list) カスタムカラーマップを構成する色のリスト。
139 :param vmin: (float, optional) カラーマップ正規化の最小値。指定されない場合は `x` の最小値。
140 :param vmax: (float, optional) カラーマップ正規化の最大値。指定されない場合は `x` の最大値。
141 :param cmap_name: (str, optional) カスタムカラーマップの名前。デフォルトは 'custom_cmap'。
142 :param nbins: (int, optional) 線形補間を行う際のビン数。デフォルトは100。
143 :returns: (numpy.ndarray) `x` の各要素に対応するRGBA色値の配列。
144 """
145 if vmin is None: vmin = np.min(x)
146 if vmax is None: vmax = np.max(x)
147
148 # Note: この行は関数自身を呼び出す(make_colorsをmake_colorsとして)ように見えますが、
149 # 既存コードの変更はルールにより行いません。本来はmake_color_mapを呼び出す意図かもしれません。
150 color_map = make_colors(x, colors, cmap_name = cmap_name, nbins = nbins)
151 norm = Normalize(vmin = vmin, vmax = vmax)
152 colors = color_map(norm(x))
153 return colors
154
155def make_colorbar(ax, x, cmap, vmin = None, vmax = None, label = None, shrink = 0.5, aspect = 10.0,
156 ticks = None, ticklabels = None):
157 """
158 概要: カラーバーを作成し、プロットに追加します。
159
160 詳細説明:
161 与えられたデータ `x` とカラーマップ `cmap` に基づいてカラーバーを生成し、
162 指定されたAxesオブジェクトに追加します。ラベル、サイズ、ティックなども設定可能です。
163
164 :param ax: (matplotlib.axes.Axes) カラーバーを追加するAxesオブジェクト。
165 :param x: (numpy.ndarray) カラーマップの正規化に使用するデータ。
166 :param cmap: (matplotlib.colors.Colormap or str) 使用するカラーマップオブジェクトまたはカラーマップ名。
167 :param vmin: (float, optional) カラーマップ正規化の最小値。指定されない場合は `x` の最小値。
168 :param vmax: (float, optional) カラーマップ正規化の最大値。指定されない場合は `x` の最大値。
169 :param label: (str, optional) カラーバーのラベル。
170 :param shrink: (float, optional) カラーバーの表示サイズの縮小率。デフォルトは0.5。
171 :param aspect: (float, optional) カラーバーのアスペクト比。デフォルトは10.0。
172 :param ticks: (list or numpy.ndarray, optional) カラーバーのティック位置。
173 :param ticklabels: (list of str, optional) カラーバーのティックラベル。
174 :returns: (matplotlib.colorbar.Colorbar) 作成されたカラーバーオブジェクト。
175 """
176 if vmin is None: vmin = np.min(x)
177 if vmax is None: vmax = np.max(x)
178
179 norm = Normalize(vmin = vmin, vmax = vmax)
180 scmap = plt.cm.ScalarMappable(cmap = cmap, norm = norm)
181 scmap.set_array(x)
182 cbar = plt.colorbar(scmap, ax = ax, shrink = shrink, aspect = aspect)
183 if label is not None: cbar.set_label(label)
184
185 if ticks is not None: cbar.set_ticks(ticks)
186 if ticklabels is not None: cbar.set_ticklabels(ticklabels)
187
188 return cbar
189
190
191def set_light(x, azdeg = 315, altdeg = 45, cmap = "viridis", vert_exag = 0.1, blend_mode = 'soft'):
192 """
193 概要: 3Dサーフェスプロットのシェーディングに光源効果を設定します。
194
195 詳細説明:
196 `matplotlib.colors.LightSource` を使用して、指定されたデータ `x` に対して光源の角度、
197 カラーマップ、垂直方向の強調、ブレンドモードを適用し、シェーディングされたRGB画像データを生成します。
198
199 :param x: (numpy.ndarray) シェーディングの基となる2Dデータ(高さ情報など)。
200 :param azdeg: (float, optional) 光源の水平方向の角度(アジマス角)。デフォルトは315度。
201 :param altdeg: (float, optional) 光源の垂直方向の角度(高度角)。デフォルトは45度。
202 :param cmap: (str or matplotlib.colors.Colormap, optional) 使用するカラーマップ。デフォルトは"viridis"。
203 :param vert_exag: (float, optional) 垂直方向の強調係数。デフォルトは0.1。
204 :param blend_mode: (str, optional) ブレンドモード('soft', 'hsv', 'overlay'など)。デフォルトは'soft'。
205 :returns: (numpy.ndarray) シェーディングが適用されたRGBカラーデータ。
206 """
207 ls = LightSource(azdeg = azdeg, altdeg = altdeg)
208 rgb = ls.shade(x, cmap = cmap, vert_exag = vert_exag, blend_mode = blend_mode)
209 return rgb
210
211def show_color_bar(fig, ax, scale, cmap, shrink = 0.5, aspect = 10.0):
212 """
213 概要: カラーバーを表示します。
214
215 詳細説明:
216 与えられたデータ `scale` とカラーマップ `cmap` に基づいてカラーバーを生成し、
217 指定されたFigureとAxesオブジェクトにアタッチします。
218
219 :param fig: (matplotlib.figure.Figure) カラーバーを配置するFigureオブジェクト。
220 :param ax: (matplotlib.axes.Axes) カラーバーを関連付けるAxesオブジェクト。
221 :param scale: (numpy.ndarray) カラーマップの正規化に使用する数値データ。
222 :param cmap: (matplotlib.colors.Colormap or str) 使用するカラーマップオブジェクトまたはカラーマップ名。
223 :param shrink: (float, optional) カラーバーの表示サイズの縮小率。デフォルトは0.5。
224 :param aspect: (float, optional) カラーバーのアスペクト比。デフォルトは10.0。
225 :returns: (matplotlib.colorbar.Colorbar) 作成されたカラーバーオブジェクト。
226 """
227 mappable = plt.cm.ScalarMappable(cmap = cmap)
228 mappable.set_array(scale)
229 cbar = fig.colorbar(mappable, ax = ax, shrink = shrink, aspect = aspect)
230 return cbar
231
232def plot_surface3d(ax, X, Y, Z, color = None, cmap = None, facecolors = None, edgecolor = 'black', alpha = 0.7, shade = True,
233 xlabel = 'X', ylabel = 'Y', zlabel = 'Z'):
234 """
235 概要: 3Dサーフェスプロットを描画します。
236
237 詳細説明:
238 与えられたX, Y, Z座標データに基づいて、3Dの曲面または面プロットを描画します。
239 色、カラーマップ、エッジ色、透明度、シェーディングなどのオプションを設定できます。軸ラベルも設定されます。
240
241 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
242 :param X: (numpy.ndarray) X座標データ。
243 :param Y: (numpy.ndarray) Y座標データ。
244 :param Z: (numpy.ndarray) Z座標データ。
245 :param color: (str or tuple, optional) サーフェスの単一色。`facecolors`または`cmap`と同時に指定すると上書きされる可能性あり。
246 :param cmap: (str or matplotlib.colors.Colormap, optional) サーフェスの色付けに使用するカラーマップ。
247 :param facecolors: (numpy.ndarray, optional) 各面の色を指定するRGBAカラー配列。
248 :param edgecolor: (str or tuple, optional) サーフェスのエッジの色。デフォルトは'black'。
249 :param alpha: (float, optional) サーフェスの透明度。0.0(完全透明)から1.0(完全不透明)の範囲。デフォルトは0.7。
250 :param shade: (bool, optional) 光源によるシェーディングを適用するかどうか。デフォルトはTrue。
251 :param xlabel: (str, optional) X軸のラベル。デフォルトは'X'。
252 :param ylabel: (str, optional) Y軸のラベル。デフォルトは'Y'。
253 :param zlabel: (str, optional) Z軸のラベル。デフォルトは'Z'。
254 :returns: (None)
255 """
256 options = {}
257 if color is not None: options['color'] = color
258 if cmap is not None: options['cmap'] = cmap
259 if facecolors is not None: options['facecolors'] = facecolors
260 if edgecolor is not None: options['edgecolor'] = edgecolor
261 if alpha is not None: options['alpha'] = alpha
262 if shade is not None: options['shade'] = shade
263
264 ax.plot_surface(X, Y, Z, **options)
265
266 ax.set_xlabel(xlabel)
267 ax.set_ylabel(ylabel)
268 ax.set_zlabel(zlabel)
269
270def plot_isosurface3d(ax, X, Y, Z, F, levels, origin, spacing,
271 colors = None, edgecolor = 'k', alpha = 0.3, linewidth = 0.1,
272 phase = None, custom_colors = None, nbins = 100, cmap_name = 'custom color',
273 minx = None, maxx = None,
274 miny = None, maxy = None,
275 minz = None, maxz = None,
276 ):
277 """
278 概要: 3Dボリュームデータから等値面を描画します。
279
280 詳細説明:
281 `skimage.measure.marching_cubes` を使用して、3Dボリュームデータ `F` から指定された
282 レベルの等値面を抽出し、3D Axes上に描画します。位相データに基づくカスタムカラーリングや、
283 凡例の追加もサポートします。
284
285 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
286 :param X: (numpy.ndarray) X座標のグリッドデータ。軸範囲設定に使用。
287 :param Y: (numpy.ndarray) Y座標のグリッドデータ。軸範囲設定に使用。
288 :param Z: (numpy.ndarray) Z座標のグリッドデータ。軸範囲設定に使用。
289 :param F: (numpy.ndarray) 等値面を抽出する3Dボリュームデータ。
290 :param levels: (list or float) 描画する等値面のレベル(値)のリスト。単一の値も可。
291 :param origin: (tuple) ボリュームデータの原点 (x, y, z)。
292 :param spacing: (tuple) ボリュームデータの各軸方向のサンプル間隔 (dx, dy, dz)。
293 :param colors: (list or str, optional) 等値面の色リスト(カスタムカラーマップが指定されていない場合)。
294 :param edgecolor: (str or tuple, optional) 等値面のエッジの色。デフォルトは'k' (黒)。
295 :param alpha: (float, optional) 等値面の透明度。デフォルトは0.3。
296 :param linewidth: (float, optional) 等値面のエッジの線の太さ。デフォルトは0.1。
297 :param phase: (numpy.ndarray, optional) 位相情報を含む3Dボリュームデータ。カスタムカラーリングに使用。
298 :param custom_colors: (list, optional) 位相に基づいて色付けするためのカスタムカラーリスト。
299 :param nbins: (int, optional) カスタムカラーマップ生成時のビン数。デフォルトは100。
300 :param cmap_name: (str, optional) カスタムカラーマップの名前。デフォルトは'custom color'。
301 :param minx: (float, optional) X軸の最小範囲。指定されない場合は `X` から自動計算。
302 :param maxx: (float, optional) X軸の最大範囲。指定されない場合は `X` から自動計算。
303 :param miny: (float, optional) Y軸の最小範囲。指定されない場合は `Y` から自動計算。
304 :param maxy: (float, optional) Y軸の最大範囲。指定されない場合は `Y` から自動計算。
305 :param minz: (float, optional) Z軸の最小範囲。指定されない場合は `Z` から自動計算。
306 :param maxz: (float, optional) Z軸の最大範囲。指定されない場合は `Z` から自動計算。
307 :returns: (None)
308 """
309 if custom_colors is not None:
310 custom_cmap = make_cmap(custom_colors, cmap_name = cmap_name, nbins = nbins)
311 else:
312 custom_cmap = None
313
314#np.ndarray([行、列、高さ])とmarching_cubesの座標[x,y,z]のインデックスがずれているようなので、修正
315 F = np.transpose(F, (1, 0, 2))
316 if phase is not None:
317 phase = np.transpose(phase, (1, 0, 2))
318 legend_patches = []
319
320# 複数の等値面を描画
321 for il, level in enumerate(levels):
322 try:
323 verts, faces, _, _ = marching_cubes(F, level = level, spacing = spacing)
324 except:
325# print(f"\nError in tkWavefunction_H.plot_isosurface3d(): ValueError: Surface level must be within volume data range.\n")
326 continue
327
328 verts += np.array(origin)
329
330 # 等値面を追加
331 if custom_cmap:
332 # 位相の計算
333 vertex_phases = np.array([phase[tuple(np.round((v - origin) / spacing).astype(int))] for v in verts])
334 norm_phases = (vertex_phases - np.min(vertex_phases)) / (np.max(vertex_phases) - np.min(vertex_phases))
335 colors = custom_cmap(norm_phases)
336 mesh = Poly3DCollection(verts[faces], alpha = alpha, edgecolor = edgecolor, linewidth = linewidth)
337 mesh.set_facecolor(colors[faces].mean(axis = 1))
338 else:
339 mesh = Poly3DCollection(verts[faces], alpha = alpha, facecolor = colors[il], edgecolor = edgecolor, linewidth = linewidth)
340 # 凡例用パッチを作成
341 legend_patches.append(Patch(facecolor = colors[il], edgecolor = edgecolor, label = f"Level = {level:.4g}"))
342
343 ax.add_collection3d(mesh)
344
345
346# 軸範囲の統一
347 X1d = X.flatten()
348 Y1d = Y.flatten()
349 Z1d = Z.flatten()
350 if minx is None: minx = min(X1d)
351 if maxx is None: maxx = max(X1d)
352 if miny is None: miny = min(Y1d)
353 if maxy is None: maxy = max(Y1d)
354 if minz is None: minz = min(Z1d)
355 if maxz is None: maxz = max(Z1d)
356# print(f"x range: {minx} - {maxx}")
357# print(f"y range: {miny} - {maxy}")
358# print(f"z range: {minz} - {maxz}")
359 ax.set_xlim([minx, maxx])
360 ax.set_ylim([miny, maxy])
361 ax.set_zlim([minz, maxz])
362
363# **アスペクト比を 1:1:1 に設定**
364 ax.set_box_aspect([1, 1, 1])
365
366# 軸ラベル
367 ax.set_xlabel("X")
368 ax.set_ylabel("Y")
369 ax.set_zlabel("Z")
370
371# 凡例を追加
372 if custom_colors is None:
373 ax.legend(handles=legend_patches, loc="upper right", fontsize=10)
374
375def contour3d(ax, X, Y, F, nbins = 50, cmap = "viridis", xlabel = 'X', ylabel = 'Y', zlabel = 'Z'):
376 """
377 概要: 3D等高線プロットを描画します。
378
379 詳細説明:
380 `matplotlib.pyplot.contour3D` を使用して、指定された2次元データ `F` の
381 3D等高線(または等高線面)プロットを描画します。
382
383 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
384 :param X: (numpy.ndarray) X座標データ。
385 :param Y: (numpy.ndarray) Y座標データ。
386 :param F: (numpy.ndarray) 等高線を描画する2Dデータ。
387 :param nbins: (int, optional) 等高線の数。デフォルトは50。
388 :param cmap: (str or matplotlib.colors.Colormap, optional) 使用するカラーマップ。デフォルトは"viridis"。
389 :param xlabel: (str, optional) X軸のラベル。デフォルトは'X'。
390 :param ylabel: (str, optional) Y軸のラベル。デフォルトは'Y'。
391 :param zlabel: (str, optional) Z軸のラベル。デフォルトは'Z'。
392 :returns: (None)
393 """
394 ax.contour3D(X, Y, F, nbins, cmap = cmap)
395
396 ax.set_xlabel(xlabel)
397 ax.set_ylabel(ylabel)
398 ax.set_zlabel(zlabel)
399
400def plot_scatter3d(ax, x, y, z, minx, maxx, miny, maxy, minz, maxz,
401 cmap = None, c = None, norm = None, marker = 'o', size = 0.5, alpha = 1.0):
402 """
403 概要: 3D散布図を描画します。
404
405 詳細説明:
406 指定されたX, Y, Z座標データに基づいて、3Dの散布図を描画します。
407 マーカーの種類、サイズ、色、透明度などを設定できます。
408
409 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
410 :param x: (numpy.ndarray) X座標データ。
411 :param y: (numpy.ndarray) Y座標データ。
412 :param z: (numpy.ndarray) Z座標データ。
413 :param minx: (float) X軸の最小範囲。
414 :param maxx: (float) X軸の最大範囲。
415 :param miny: (float) Y軸の最小範囲。
416 :param maxy: (float) Y軸の最大範囲。
417 :param minz: (float) Z軸の最小範囲。
418 :param maxz: (float) Z軸の最大範囲。
419 :param cmap: (str or matplotlib.colors.Colormap, optional) 色付けに使用するカラーマップ。
420 :param c: (numpy.ndarray or str, optional) 各点の色の配列、または単一色。
421 :param norm: (matplotlib.colors.Normalize, optional) カラーマップの正規化オブジェクト。
422 :param marker: (str, optional) マーカーのスタイル。デフォルトは'o' (円)。
423 :param size: (float, optional) マーカーのサイズ。デフォルトは0.5。
424 :param alpha: (float, optional) マーカーの透明度。デフォルトは1.0。
425 :returns: (matplotlib.collections.PathCollection) 作成された散布図コレクションオブジェクト。
426 """
427 options = {}
428 if cmap is not None: options["cmap"] = cmap
429 if c is not None : options["c"] = c
430 if norm is not None: options["norm"] = norm
431 if size is not None: options["s"] = size
432 if alpha is not None: options["alpha"] = alpha
433
434 sc = ax.scatter(x, y, z, marker = marker, **options)
435
436 ax.set_xlim([minx, maxx])
437 ax.set_ylim([miny, maxy])
438 ax.set_zlim([minz, maxz])
439 ax.set_xlabel('X')
440 ax.set_ylabel('Y')
441 ax.set_zlabel('Z')
442
443 return sc
444
445def plot_contour2d_xy(ax, x, y, offsetz, f, cmap, levels, alpha):
446 """
447 概要: XY平面に投影された2D等高線プロットを描画します。
448
449 詳細説明:
450 指定されたデータ `f` に基づいて、X-Y平面に平行な`offsetz`の高さに2D等高線塗りつぶしプロットを描画します。
451
452 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
453 :param x: (numpy.ndarray) X座標データ。
454 :param y: (numpy.ndarray) Y座標データ。
455 :param offsetz: (float) 等高線プロットを配置するZ軸のオフセット値。
456 :param f: (numpy.ndarray) 等高線を描画する2Dデータ。
457 :param cmap: (str or matplotlib.colors.Colormap) 使用するカラーマップ。
458 :param levels: (int or list) 等高線の数またはレベルのリスト。
459 :param alpha: (float) 等高線プロットの透明度。
460 :returns: (None)
461 """
462 ax.contourf(x, y, f, zdir = 'z', offset = offsetz, cmap = cmap, levels = levels, alpha = alpha)
463
464def plot_contour2d_yz(ax, offsetx, y, z, f, cmap, levels, alpha):
465 """
466 概要: YZ平面に投影された2D等高線プロットを描画します。
467
468 詳細説明:
469 指定されたデータ `f` に基づいて、Y-Z平面に平行な`offsetx`の位置に2D等高線塗りつぶしプロットを描画します。
470
471 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
472 :param offsetx: (float) 等高線プロットを配置するX軸のオフセット値。
473 :param y: (numpy.ndarray) Y座標データ。
474 :param z: (numpy.ndarray) Z座標データ。
475 :param f: (numpy.ndarray) 等高線を描画する2Dデータ。
476 :param cmap: (str or matplotlib.colors.Colormap) 使用するカラーマップ。
477 :param levels: (int or list) 等高線の数またはレベルのリスト。
478 :param alpha: (float) 等高線プロットの透明度。
479 :returns: (None)
480 """
481 ax.contourf(f, y, z, zdir = 'x', offset = offsetx, cmap = cmap, levels = levels, alpha = alpha)
482
483def plot_contour2d_zx(ax, x, offsety, z, f, cmap, levels, alpha):
484 """
485 概要: ZX平面に投影された2D等高線プロットを描画します。
486
487 詳細説明:
488 指定されたデータ `f` に基づいて、Z-X平面に平行な`offsety`の位置に2D等高線塗りつぶしプロットを描画します。
489
490 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
491 :param x: (numpy.ndarray) X座標データ。
492 :param offsety: (float) 等高線プロットを配置するY軸のオフセット値。
493 :param z: (numpy.ndarray) Z座標データ。
494 :param f: (numpy.ndarray) 等高線を描画する2Dデータ。
495 :param cmap: (str or matplotlib.colors.Colormap) 使用するカラーマップ。
496 :param levels: (int or list) 等高線の数またはレベルのリスト。
497 :param alpha: (float) 等高線プロットの透明度。
498 :returns: (None)
499 """
500 ax.contourf(x, f, z, zdir = 'y', offset = offsety, cmap = cmap, levels = levels, alpha = alpha)
501
502def plot_contours_xyz_by_func(ax, func, minx, maxx, nmesh = 100,
503 posx = 0.1, posy = 0.1, posz = 0.1,
504 offsetx = None, offsety = None, offsetz = None,
505 cmap = None, levels = 20, alpha = 0.3):
506 """
507 概要: 関数から計算されたデータに基づき、XYZの各平面に投影された2D等高線プロットを描画します。
508
509 詳細説明:
510 ユーザー定義関数 `func` を使用してX, Y, Z軸の各断層面におけるデータを計算し、
511 それぞれの平面(YZ、XY、ZX)に2D等高線塗りつぶしプロットを描画します。
512
513 :param ax: (matplotlib.axes.Axes) プロットを描画する3D Axesオブジェクト。
514 :param func: (callable) (x, y, z) を引数にとり、スカラー値を返す関数。
515 :param minx: (float) 座標範囲の最小値。
516 :param maxx: (float) 座標範囲の最大値。
517 :param nmesh: (int, optional) メッシュの点数。デフォルトは100。
518 :param posx: (float, optional) YZ平面プロット用のX軸固定位置。デフォルトは0.1。
519 :param posy: (float, optional) ZX平面プロット用のY軸固定位置。デフォルトは0.1。
520 :param posz: (float, optional) XY平面プロット用のZ軸固定位置。デフォルトは0.1。
521 :param offsetx: (float, optional) YZ平面プロットのX軸オフセット。指定されない場合は`minx`。
522 :param offsety: (float, optional) ZX平面プロットのY軸オフセット。指定されない場合は`maxx`。
523 :param offsetz: (float, optional) XY平面プロットのZ軸オフセット。指定されない場合は`minx`。
524 :param cmap: (str or matplotlib.colors.Colormap, optional) 使用するカラーマップ。
525 :param levels: (int or list, optional) 等高線の数またはレベルのリスト。デフォルトは20。
526 :param alpha: (float, optional) 等高線プロットの透明度。デフォルトは0.3。
527 :returns: (None)
528 """
529 x1 = np.linspace(minx, maxx, nmesh)
530 y1 = np.linspace(minx, maxx, nmesh)
531 z1 = np.linspace(minx, maxx, nmesh)
532 if offsetx is None: offsetx = minx
533 if offsety is None: offsety = maxx
534 if offsetz is None: offsetz = minx
535
536 yp, zp = np.meshgrid(y1, z1, indexing = 'ij')
537 fp = func(posx, yp, zp)
538 plot_contour2d_yz(ax, offsetx, yp, zp, fp, cmap = cmap, levels = 20, alpha = 0.3)
539
540 xp, yp = np.meshgrid(x1, y1, indexing = 'ij')
541 fp = func(xp, yp, posz)
542 plot_contour2d_xy(ax, xp, yp, offsetz, fp, cmap = cmap, levels = 20, alpha = 0.3)
543
544 xp, zp = np.meshgrid(x1, z1, indexing = 'ij')
545 fp = func(xp, posy, zp)
546 plot_contour2d_zx(ax, xp, offsety, zp, fp, cmap = cmap, levels = 20, alpha = 0.3)
547
548def main():
549 """
550 概要: トーラスを3Dでプロットするデモンストレーション関数です。
551
552 詳細説明:
553 トーラスのパラメトリック方程式を用いてX, Y, Z座標を生成し、
554 カスタムカラーマップを適用して3Dサーフェスプロットとして表示します。
555 結果は画像ファイルとして保存され、画面にも表示されます。
556
557 :returns: (None)
558 """
559# トーラスのパラメータ
560 R = 3 # 大半径
561 r = 1 # 小半径
562
563# パラメトリック変数
564 theta = np.linspace(0, 2 * np.pi, 100)
565 phi = np.linspace(0, 2 * np.pi, 100)
566 theta, phi = np.meshgrid(theta, phi)
567
568# トーラスの式
569 X = (R + r * np.cos(theta)) * np.cos(phi)
570 Y = (R + r * np.cos(theta)) * np.sin(phi)
571 Z = r * np.sin(theta)
572
573# カスタムカラーマップの定義
574 colors = [(1, 0.5, 0.5), (0, 1, 0), (1, 0.5, 0.5)] # 薄い赤から青、符水赤へのグラデーション
575 # Note: make_color_map 関数内で `norm` 変数が未定義のため、この呼び出しは実行時にエラーになる可能性があります。
576 color_map = make_color_map(phi, colors, cmap_name = 'custom_reds', nbins = 100)
577
578# プロット
579 fig = plt.figure()
580 ax = fig.add_subplot(111, projection='3d')
581
582 plot_surface3d(ax, X, Y, Z, facecolors = color_map, edgecolor = 'none', alpha = 0.7, shade = True)
583
584 plt.savefig('torus.png')
585 plt.show()
586
587
588if __name__ == "__main__":
589 main()