1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【matplotlib入門】3dプロットで遊んでみた♬

Last updated at Posted at 2021-02-20

何度も描いてきたような気がするが、今回も探したので、3dプロットの簡単な例をまとめておきます。
###やったこと
・欲しかった図
・オリジナルのデータ
・カラーバーの合成
・hexbinで描画
・自前関数の欲しかった図を作成
###・欲しかった図
なんの変哲もない以下の右の図を探しました。
orijinal.png

ありそうで、matplotlibのexampleからもなかなか見つからないので、以下の過去記事から見つけて、ax4.pcolormesh(f(x1, y1), cmap='hsv')を採用。
(追記)以下のThe mplot3d Toolkitとpcolormeshに例題がありました。
【参考】
【matplotlib基本】動的グラフを書いてみる♬~動画出力;Gifアニメーション
The mplot3d Toolkit
pcolormesh

pcolormeshの使い方のコード
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D 

#---
from mpl_toolkits.mplot3d.axes3d import get_test_data
X, Y, Z = get_test_data(0.05)

fig = plt.figure(figsize=(12, 6))
ax1 = fig.add_subplot(1, 2, 1, projection='3d')
hs = ax1.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='hsv') # cm.viridis
#fig.colorbar(hs, ax=ax1)

ax2 = fig.add_subplot(1, 2, 2)
hv = ax2.pcolormesh(X,Y,Z, cmap='hsv')
fig.colorbar(hv, ax=ax2)
plt.pause(1)
plt.savefig('orijinal.png')
plt.close()

【参考】
Source code for mpl_toolkits.mplot3d.axes3d

get_test_dataのコード(参考より)
def get_test_data(delta=0.05):
    """Return a tuple X, Y, Z with a test data set."""
    x = y = np.arange(-3.0, 3.0, delta)
    X, Y = np.meshgrid(x, y)

    Z1 = np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi)
    Z2 = (np.exp(-(((X - 1) / 1.5)**2 + ((Y - 1) / 0.5)**2) / 2) /
          (2 * np.pi * 0.5 * 1.5))
    Z = Z2 - Z1

    X = X * 10
    Y = Y * 10
    Z = Z * 500
    return X, Y, Z

###・オリジナルのデータ
orijinal2.png
参考は、3dプロットをsubplotとして並べられる(配置アレンジできる)ことを有意義としているようだが、今では普通にいろいろなところで使われている。むしろ、オリジナルデータの使い方が美味しそうです。
【参考】
What's New 1 Subplot3d

オリジナルデータの使い方のコード
fig = plt.figure(figsize=(12, 6))

ax = fig.add_subplot(1, 2, 1, projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.viridis,
                       linewidth=0, antialiased=False)
ax.set_zlim3d(-1.01, 1.01)
fig.colorbar(surf, shrink=0.5, aspect=5)

ax = fig.add_subplot(1, 2, 2, projection='3d')
#X, Y, Z = get_test_data(0.05)
ax.plot_wireframe(X, Y, Z, rstride=2, cstride=2)

plt.pause(1)
plt.savefig('orijinal2.png')
plt.close()

###・カラーバーの合成
ここでは、負値と正値で一度描画して、それを合成したものを示している。
単純な合成だと思っていたが、3つ目の絵を見ると再計算しているようだ。
因みに、pos; cmap='Blues', neg; cmap='Reds_r', 最後のものはcmap='RdBu'で描画している。
単純に'hsv'で描画したものが、上のように書けているので異なっているようだ。
AddClolorbar.png
AddClolorbar3.png
AddClolorbar2.png
【参考】
Colorbar

カラーバーの合成のコード
#https://matplotlib.org/stable/gallery/color/colorbar_basics.html#sphx-glr-gallery-color-colorbar-basics-py

import numpy as np
import matplotlib.pyplot as plt

# setup some generic data
N = 37
#X, Y, Z = get_test_data(0.05)
#x, y = X, Y #np.mgrid[:N, :N]
#Z = Z #(np.cos(x*0.2) + np.sin(y*0.3))
x, y = np.mgrid[:N, :N]
Z = (np.cos(x*0.2) + np.sin(y*0.3))


# mask out the negative and positive values, respectively
Zpos = np.ma.masked_less(Z, 0)
Zneg = np.ma.masked_greater(Z, 0)

fig, (ax1, ax2, ax3) = plt.subplots(figsize=(13, 3), ncols=3)

# plot just the positive data and save the
# color "mappable" object returned by ax1.imshow
pos = ax1.imshow(Zpos, cmap='Blues', interpolation='none')

# add the colorbar using the figure's method,
# telling which mappable we're talking about and
# which axes object it should be near
fig.colorbar(pos, ax=ax1)

# repeat everything above for the negative data
neg = ax2.imshow(Zneg, cmap='Reds_r', interpolation='none')
fig.colorbar(neg, ax=ax2)

# Plot both positive and negative values between +/- 1.2
pos_neg_clipped = ax3.imshow(Z, cmap='RdBu', vmin=-1.2, vmax=1.2,
                             interpolation='none')
# Add minorticks on the colorbar to make it easy to read the
# values off the colorbar.
cbar = fig.colorbar(pos_neg_clipped, ax=ax3, extend='both')
cbar.minorticks_on()
plt.savefig('AddClolorbar.png')
plt.pause(1)
plt.close()

###・hexbinで描画
これは、調べていると見つけたので、示しておく。コードは分かるがやっている処理内容は完全には理解できない。以下の参考では、scatterをhexbinで置き換えるとと言っているが、上記のX,Y,Zで描画しても綺麗な絵は得られない。
hexbin.png

【参考】
Hexbin Demo

hexbinで描画のコード
#https://matplotlib.org/stable/gallery/statistics/hexbin_demo.html#sphx-glr-gallery-statistics-hexbin-demo-py

import numpy as np
import matplotlib.pyplot as plt

# Fixing random state for reproducibility
np.random.seed(19680801)

n = 100000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
xmin = x.min()
xmax = x.max()
ymin = y.min()
ymax = y.max()

fig, axs = plt.subplots(ncols=2, sharey=True, figsize=(7, 4))
fig.subplots_adjust(hspace=0.5, left=0.07, right=0.93)
ax = axs[0]
hb = ax.hexbin(x, y, gridsize=50, cmap='inferno')
ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax))
ax.set_title("Hexagon binning")
cb = fig.colorbar(hb, ax=ax)
cb.set_label('counts')

ax = axs[1]
hb = ax.hexbin(x, y, gridsize=50, bins='log', cmap='inferno')
ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax))
ax.set_title("With a log color scale")
cb = fig.colorbar(hb, ax=ax)
cb.set_label('log10(N)')

plt.pause(1)
plt.savefig('hexbin.png')
plt.close()
###・自前関数の欲しかった図を作成 最後にオリジナルな関数の上記プロットを試みた。 結果は、以下の通り綺麗に描けました。 ![orijinal3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/6ef74d1e-ca0a-2d98-5a81-fc31b96c1d52.png) ![orijinal4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/78521788-d1dc-4fd2-46a5-2423d13b78c7.png)
自前関数の描画コード
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D 

#---
from mpl_toolkits.mplot3d.axes3d import get_test_data
def func(x, y):
    return x*x + 0.1*y*y #+x*y

#X, Y, Z = get_test_data(0.05)
X = np.arange(-15, 15, 1)
Y = np.arange(-15, 15, 1)
X, Y = np.meshgrid(X, Y)
R = X*X + 0.1*Y*Y
Z = R
#print(Z)

fig = plt.figure(figsize=(12, 6))
ax1 = fig.add_subplot(1, 2, 1, projection='3d')
hs = ax1.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='hsv') # cm.viridis
fig.colorbar(hs, ax=ax1)

ax2 = fig.add_subplot(1, 2, 2)
hv = ax2.pcolormesh(X,Y,Z, cmap='hsv')
fig.colorbar(hv, ax=ax2)
plt.pause(1)
plt.savefig('orijinal3.png')
plt.close()

#---
fig = plt.figure(figsize=(12, 6))

ax = fig.add_subplot(1, 2, 1)
X = np.arange(-15, 15, 1)
Y = np.arange(-80, 80, 5)
X, Y = np.meshgrid(X, Y)
R = func(X,Y) #X*X + 0.01*Y*Y #np.sqrt(X**2 + Y**2)
Z = R #np.sin(R)
#print(Z)
#surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.viridis,linewidth=0, antialiased=False)
surf = ax.pcolormesh(X,Y,Z, cmap='hsv')
#ax.set_zlim3d(-1.01, 1.01)
fig.colorbar(surf, shrink=0.5, aspect=5)

ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot_wireframe(X, Y, Z, rstride=2, cstride=2)

plt.pause(1)
plt.savefig('orijinal4.png')
plt.close()
最後に、描画時の配色が気に入らないので変更する 【参考】 ・[Choosing Colormaps in Matplotlib](https://matplotlib.org/stable/tutorials/colors/colormaps.html) ということで、やはり日本人の感覚だと'jet'ですね♬ ![orijinal5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/1bc45915-ae1e-e306-3e07-2752bc060803.png) ![orijinal6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/298c8233-3b12-3500-2436-d775c3a91482.png)

###まとめ
・3dプロットで遊んでみた♬
・自前関数で、3d描画、2dマップ、ワイヤーフレーム、そしてcolorbarを使えるようになった

書いた時点で以下を発見、合わせるといい感じです。、
【参考】
[Pythonによる科学・技術計算] 2次元(カラー)等高線等の描画,可視化,matplotlib
ということで、等高線追記です。
orijinal7.png

自前関数の等高線追記描画コード
#---
fig = plt.figure(figsize=(12, 6))

ax = fig.add_subplot(1, 2, 1)
X = np.arange(-15, 15, 1)
Y = np.arange(-80, 80, 5)
X, Y = np.meshgrid(X, Y)
R = func(X,Y) #X*X + 0.01*Y*Y #np.sqrt(X**2 + Y**2)
Z = R #np.sin(R)
#print(Z)
#surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.viridis,linewidth=0, antialiased=False)
surf = ax.pcolormesh(X,Y,Z, cmap='jet')
#ax.set_zlim3d(-1.01, 1.01)
fig.colorbar(surf, shrink=0.5, aspect=5)
# 等高線図の生成。
cont=ax.contour(X,Y,Z,  10, Vmax=1,colors=['white'])
cont.clabel(fmt='%1.1f', fontsize=14)

ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot_wireframe(X, Y, Z, rstride=2, cstride=2)

plt.pause(1)
plt.savefig('orijinal7.png')
plt.close()
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?