LoginSignup
1
2

More than 3 years have passed since last update.

Julia: Plotsのsurface plotに行列の色をマップする

Posted at

Introduction

Juliaで3Dのサーフェスプロットをしていて,サーフェスの色を行列で指定する際に躓いた際の備忘録.
JuliaではPlotsを用いていますが,球を普通に3D surfaceでプロットすると,左図のようにzの値に応じて色のマッピングが行われます.本記事の目的は,これを右図のように,別の行列で指定できるようにすることです.
image.png

実行環境

  • 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()
1
2
1

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