Introduction
Juliaで3Dのサーフェスプロットをしていて,サーフェスの色を行列で指定する際に躓いた際の備忘録.
JuliaではPlotsを用いていますが,球を普通に3D surfaceでプロットすると,左図のようにzの値に応じて色のマッピングが行われます.本記事の目的は,これを右図のように,別の行列で指定できるようにすることです.
実行環境
- Windows 10 Pro
- Julia 1.5.3
- VS Code
参考サイト
同様の方法を探す質問が他のサイトでも行われていました.最終的には1つ目のリンクについた回答に答えがありました.Plotsを使わず,PyPlotを用いる場合は,3つ目のリンクに回答があります.
- Plots.jl - Map surface color to matrix
- Julia PyPlot: plot 3D surface with as face colors the norm of surface gradient
- gizmaa/Plot_Examples.md
ソースコード
こちらのサイト(gizmaa/Plot_Examples.md)を参考に,球体のコードと,表面にマッピングするランダムな値の入った行列を準備します.
using Plots
pyplot() # pyplotをバックエンドに指定
u = range(0.0,2pi,length=100);
v = range(0.0,pi,length=100);
lu = length(u);
lv = length(v);
x = zeros(lu,lv);
y = zeros(lu,lv);
z = zeros(lu,lv);
colors = zeros(lu,lv);
colortube = 0.001:0.001:1.0;
for uu=1:lu
for vv=1:lv
x[uu,vv]= cos(u[uu])*sin(v[vv]);
y[uu,vv]= sin(u[uu])*sin(v[vv]);
z[uu,vv]= cos(v[vv]);
end
end
for uu=1:lu
for vv=1:lv
colors[uu,vv]=rand(colortube);
end
end
Plotsで行列をサーフェスプロットの色としてマッピングするには,キーワードfill_z
に行列を指定するそうです.
# show results
plt = plot(x,y,z,
fill_z=abs.(colors),
st=:surface,
colorbar_title="Color",
)
display(plt)
これで,上記右図のプロットが生成されます.このfill_z
のキーワードを探すのに苦心しました.facecolors
等,色々試していました...
キーワードを知らないときには,Plots.jlのソースコードを見るしかないのでしょうか.普段はDocumentationの整備されたMATLABのユーザーなので,他の言語での探し方がいまいちわかっていません.
Plotsを用いて作成したグラフは以下のコードを用いて,実行中のソースファイルと同名で保存しています.
# save
runningfilename = splitext(splitpath(@__FILE__)[end])[1]
savefig(plt,runningfilename)
PyPlotの場合
上記参考サイトの三番目にあるように,Pyplotの場合は以下のようにすればプロットできます.colors
の形が,MATLABで私がよく使う形(メッシュグリッド的な指定)と違っていたりするので,私は使いません.
# reproduced from https://gist.github.com/gizmaa/7214002#3d-surf-plot
using PyPlot
#######
omit definition of u,v
#######
colors = zeros(lu,lv,3) ;
colortube = 0.001:0.001:1.0;
for uu=1:lu
for vv=1:lv
x[uu,vv]= cos(u[uu])*sin(v[vv]);
y[uu,vv]= sin(u[uu])*sin(v[vv]);
z[uu,vv]= cos(v[vv]);
end
end
for uu=1:lu
for vv=1:lv
for ii=1:3
colors[uu,vv,ii]=rand(colortube);
end
end
end
fig=surf(x,y,z,facecolors=colors);
gcf()