en_US English ja 日本語 zh_CN 中文

python3でランダムな強度座標で描かれた画像をグリッドの定点座標で描写し直す

また投稿タイトルがイマイチしっくりこなかったのだけど、やりたかったことといえば割とランダムなXY座標点の強度(x,y,I)で描かれている画像を、例えばx,y座標0.1刻みずつといった定点のグリッドの強度座標に直したかったということ。

データは以下のような感じ。ある程度格子に近い座標にデータはあるけれど、それぞれの座標は定点に乗っているわけではないという感じ。

X Y I

-0.87 -0.84 3.5
-0.32 -0.83 10
-0.09 -0.85 4.5
0.08 -0.87 5.3
0.35 -0.88 6.2
0.90 -0.84 3.1

-0.85 -0.74 4.5
-0.31 -0.73 15
-0.13 -0.75 2.2
0.07 -0.77 3.6
0.35 -0.78 11
0.88 -0.74 5.2

... ... ...

-0.86 0.84 35
-0.33 0.83 12
-0.12 0.85 53
0.11 0.87 12
0.32 0.88 18
0.94 0.84 19

大概の場合このままのランダム座標で処理して困ることもないのだけど、別の座標系に変換したいってときにグリッドデータから変換したほうが都合が良かったってことがあって、座標点をグリッドの定点に書き換えるってことを試したのがこの投稿。

とりあえずtkinterでdataの読み込み。

tk = Tk()
tk.withdraw()
print ('select a data files')
filenames = tkfd.askopenfilenames(filetypes= [('text','*.dat')], initialdir='./DATA')
tkms.showinfo('file paths are',filenames)
tk.destroy()
data = [0]*len(filenames)
basename = [0]*len(filenames)
for i in range(len(filenames)):
  data[i] = np.loadtxt(filenames[I])
  basename[i] = os.path.basename(filenames[i]+str(i)+'.txt')

scipyのinterpolate.griddataで強度座標の変更

使ったのはscipyのinterpolate.griddataを試してみることに。

展開するためのグリッド座標点を準備する。numpyのmgridなりmeshgridなりを使って。

#meshgridで。グリッドの粗さはdataに合わせて
xi = np.linspace(-0.1,0.1,100)
yi = np.linspace(-0.1,0.1,100)
x_grid,y_grid = np.meshgrid(xi,yi)
#mgridならこんな感じ
x_grid,y_grid = np.mgrid[-0.1:0.1:101j,-0.1:0.1:101j]

読み込んだdataを並び換えてから、griddataを使う。interpolateのオプションは3種類cubic, linear, nearest。

for i in range(len(filenames)):
  coords=np.vstack((data[i][:,0].flatten(),data[i][:,1].flatten())).T
  grid_data1 = griddata(coords,data[i][:,2].flatten(),(x_grid,y_grid),method='cubic')
  grid_data2 = griddata(coords,data[i][:,2].flatten(),(x_grid,y_grid),method='linear')
  grid_data3 = griddata(coords,data[i][:,2].flatten(),(x_grid,y_grid),method='nearest)

できた座標をpyplotのscatterを使ってプロット。

  r_min = 0
  r_max = -1
  v_min=0
  v_max=50
  fig,ax=plt.subplots(2,2)
  ax[0,0].scatter(data[i][r_min:r_max,0],data[i][r_min:r_max,1],c=data[i][r_min:r_max,2],cmap=cm.gist_rainbow,marker='s',vmin=v_min,vmax=v_max,s=plotsize)
  ax[0,0].title.set_text('original')
  ax[0,1].scatter(x_grid,y_grid,c=grid_data1,cmap=cm.gist_rainbow,marker='s',vmin=v_min,vmax=v_max,s=plotsize)
  ax[0,1].title.set_text('cubic')
  ax[1,0].scatter(x_grid,y_grid,c=grid_data2,cmap=cm.gist_rainbow,marker='s',vmin=v_min,vmax=v_max,s=plotsize)
  ax[1,0].title.set_text('linear')
  ax[1,1].scatter(x_grid,y_grid,c=grid_data3,cmap=cm.gist_rainbow,marker='s',vmin=v_min,vmax=v_max,s=plotsize)
  ax[1,1].title.set_text('nearest')
  #なんか良い方法が見つからなかったんだけど軸設定はもう少しスッキリかける?
  ax[0,0].set_xlim(-0.1,0.1)
  ax[0,1].set_xlim(-0.1,0.1)
  ax[1,0].set_xlim(-0.1,0.1)
  ax[1,1].set_xlim(-0.1,0.1)
  ax[0,0].set_ylim(-0.1,0.1)
  ax[0,1].set_ylim(-0.1,0.1)
  ax[1,0].set_ylim(-0.1,0.1)
  ax[1,1].set_ylim(-0.1,0.1)
  plt.savefig('FIGURE/TEST/'+'griddata'+basename[i]+'orig.png')

それで画像はこんな感じ。

griddata

見た感じcubicとlinearはそれなりに良さそうに見える。実際にこんな座標変換が許されるかはデータと目的次第でしょうので、必要なデータ処理にバイアスがかかってないかはチェックする必要があるでしょう。

さて、これでだいたい良いって場合もあるかもしれないけれど、このdataの場合だと中心のマスク部分の座標点が取り除かれている処理がされているので、その座標点分がintnerpolateで高強度に染められてしまうという問題?が。

numpyのmeshgridをマスクする

そもそもscipyの違うモジュールでやるって手もあるんだろうけど、今回は単純にグリッドの座標にマスクを追加して修正。

#mask xy grid for center
  x1,x2,y1,y2 = 0.0125, -0.0101, 0.0138, -0.0152
  rect = (x_grid < x1) & (x_grid>x2) & (y_grid < y1) & (y_grid > y2)
  x_grid=x_grid[~rect]
  y_grid=y_grid[~rect]

もしくはnanに変更するとか。

  x_grid[rect]=np.nan
  y_grid[rect]=np.nan

これで画像はこんな感じに。ちょっとマスクのサイズ間違ってるっぽいけど、まあ良いでしょう。

maskをつけて

という感じで一応定点グリッドに座標を移し替えられました、という投稿でした。

関連記事

1. pythonのまとめ

D

 

 

en_US English ja 日本語 zh_CN 中文

Mac OS をcatalinaにアップデートしたらpyopenclにエラーが出るのでその対策

MacOSをアップデートしたらpythonプログラム走らせるのにエラーが出る様になった話。簡単に対応はできるけど、いつも忘れるので一応投稿しておく。

エラーは以下の様な感じ。

pyopencl._cl.RuntimeError: clBuildProgram failed: BUILD_PROGRAM_FAILURE

対策は

export PYOPENCL_NO_CACHE=1

をプログラム使う前にexportするだけ。

.bash_profile 

に書きこんどきゃいいのかな。あれ、macてzshに変わったんだっけ。.zshrcを編集しなきゃなのかと思ったら、bash_profileしか見つからない。んー、どうなってるんだろ。

D

en_US English ja 日本語 zh_CN 中文

python3のmatplotlibでグラフを出力する時のグラフサイズの調整

普段プログラム中でmatplotlibを使うときは、随所でplt.plot()でプロットしてplt.show()で確認しつつplt.savefig(bbox_inches=’tight’)で保存してって感じで使っていることが多い。

それはそれでいいのだけど、いくつかの同じタイプの絵をまとめて他の人に見せようと思ったら微妙に軸の長さがずれている。なんでかなってみてたら、X軸のラベルのサイズで全体のスケールが変わっていた模様。これをどうしたら直せるのかと、bbox_inchesとtight_layoutのオプションをいじりながら遊んでみたのが今回の投稿。

……ってなことをやろうと思って書いてたんだけど、書き終わってみたらbbox_inchesを普通に使うんで問題なかった。悲しい。なんで最初の絵ずれてたんだろ、多分変なことしてたんだと思う。

rcParamsでまずは全体のプロットの外観調整

plt.rcParams['font.family']='Arial'
plt.rcParams['font.size']= 14
plt.rcParams['axes.linewidth']=2.5
plt.rcParams['xtick.major.width']=2.5
plt.rcParams['xtick.labelsize']=14
plt.rcParams['ytick.major.width']=2.5
plt.rcParams['ytick.labelsize']=14
plt.rcParams['figure.figsize']=(4,4)

rcParamsを使うのがいいのかは知らないけど、大体のセッティングを最初にできるので大概のプログラムでは突っ込んでいる。figsizeが基本的に絵のサイズ。

plotはまあなんでもいいのだけど、一応以下のようなプロット。一応subplotsを使う設定で。

#Xラベルの長さを変える
Title = ['aaa','bbb','ccc','ddd','eee','fff']
#Title2 = ['aaaaaa','bbbbbb','cccccc','dddddd','eeeeee','ffffff']
data1=np.array([165,201,224,158,178,207])
Err1=np.array([1,4,1,2,4,10])
data2=np.array([380,420,418,435,412,409])
Err2=np.array([10,19,12,20,18,34])
fig, ax1 = plt.subplots()
ax1.set_ylabel('y1',fontname='Arial')
ax1.errorbar(Title,data1,yerr=Err1,capsize=10,marker='o',ms=11,color='orange',fillstyle='none',linestyle = 'None')
ax2=ax1.twinx()
ax2.set_ylabel('y2',fontname='Arial')
ax2.errorbar(Title,data2,yerr=Err2,capsize=10,marker='D',ms=11,color='b',fillstyle='none',linestyle = 'None')

このプロット用の描画設定。

ax1.tick_params(axis ='x', which ='both', top='off',bottom='off', pad=10)
ax1.set_ylim(150,250)
ax1.set_yticks([150,200,250])
ax1.tick_params('x',labelrotation=90)
ax2.set_ylim(250,650)
ax2.set_yticks([200,400,600,800])

絵のセーブのオプションでサイズの最終調整。

bbox_inchesの場合。

fig.savefig('FIGURE/test1.png',bbox_inches='tight')

bbox_inchesでpad_inchesも0にして。

fig.savefig('FIGURE/test2.png',bbox_inches='tight',pad_inches=0)

tight_layoutを使って。

fig.tight_layout()
fig.savefig('FIGURE/test3.png')

ちなみにpyplotからplt.savefigにしても違いはない。

1個目。

test1

2個目。

test2

3個目

test3

 

というわけでbbox_inchesを使っておけば問題ない。

むしろtight_layourt()の方がラベルサイズとか揃ってないプロットにはよくなさげ。画像の全体サイズを合わせたいならこっちだけど。

下のように軸の高さ・幅を抜いて割らないとってなぜか最初に思ってたんだけど、別にそんなことはなかった。

width = ax1.figure.subplotpars.right-ax1.figure.subplotpars.left
height = ax1.figure.subplotpars.top-ax1.figure.subplotpars.bottom
ax1.figure.set_size_inches(4/width,4/height)

まあ、あとで何かに使えるかもしれないし、一応載せておく。任意の長さに軸サイズを調整したいって時なんかに使えるのかな。

うん、久しぶりにちょっと意味不明な投稿だ。

関連記事

1. pythonのまとめ

D

en_US English ja 日本語 zh_CN 中文

python3でnanが入ってるデータを取り使う場合

生データにnanが入ってるってことはそれなりによくある。

nan入っててもそのまま処理してくれたり、nan_policyとかを手動でセットすればオーケって場合は楽なんだけど、そうでない場合もあって結構めんどくさいことも。

それでどうするかっていうと、まあ状況によってnanを0にしたり、infにしたり、周りの値の平均値にしたり、含む行を削除しちゃったり、などなど。

numpyのndarrayにnanがいる場合

データは2列複数行のndarray。

isnan()でnanの場所を探して書き換える。

data[i][np.isnan(data[i])]=0
data[i][np.isnan(data[i])]=np.inf

など。

同じくisnan()で探して含む行を削除する

こうやってanyを使って抽出するってのが一番シンプル? 文字数も少ないし。

data[i]=data[i][~np.isnan(data[i]).any(axis=1)]

deleteを使って書くならこんな感じかな? データによって少し変える必要があるかもしれないが。私のは2列目にnanが入ってるのでこう書いた。

 data[i] = np.delete(data[i],np.where(np.isnan(data[i][:,1])),axis=0)

今の所はこのくらい。

pandasとか他の形式で扱うことがあったら追記する。

関連記事

1. pythonのまとめ

D

en_US English ja 日本語 zh_CN 中文

python3を使ってx軸が角度の2列xyデータで、角度をずらして取り扱う

ちょっと、いやかなりタイトルが微妙。

やりたかったことは、xyデータのx軸が0−360度のデータなんだけど、元々のデータセットだとピークが見にくいので90度ずらしたいというだけ。つまりは下図。わかりやすい日本語タイトルが思いつく人間になりたい。

プロット

データ。

1 100
2 200
3 400
4 1000
… …
360 80

てな感じの360行。

スクリプト。

filenames = tkfd.askopenfilenames(filetypes= [("all files","*"),('text','*.txt'),('text','*.dat')], initialdir='./DATA')
for i in range(len(filenames)):
  data[i] =np.loadtxt(filenames[i],comments='#',skiprows=1)
  basename[i] = os.path.basename(filenames[i]+str(i)+'.txt')
#データの並び替え。ここでは90度ずらしてるけど何度でもいい。角度を変えたらあとのfor文の長さも修正する。
  data[i][:,:]=np.vstack((data[i][90:360,:],data[i][0:90,:]))
#X軸の修正。ベターな書き方ありそう。
  for j in range(90):
    data[i][269+j,0] = 360+j
  plt.plot(data[i][:,0],data[i][:,1],'x',ms=10)
  plt.savefig('./FIGURE/HERMANS/'+'Dataprocess'+str(i)+'.png',bbox_inches='tight')

という感じ。

関連記事

1. pythonのまとめ

D

en_US English ja 日本語 zh_CN 中文

python3のmatplotlibで散布図作製

plotでプロットするだけ。特に注意事項もないので、スクリプトだけ。

#描画設定
plt.rcParams['font.family']='Arial'
plt.rcParams['font.size']= 14
plt.rcParams['axes.linewidth']=2.5
plt.rcParams['xtick.major.width']=2.5
plt.rcParams['xtick.labelsize']=14
plt.rcParams['ytick.major.width']=2.5
plt.rcParams['ytick.labelsize']=14
plt.rcParams['figure.figsize']=(4,4)
#x、y軸の値。今回は文字列に対してプロット
Title = ['x1','x2','x3','x4','x5','x6']
y1 = np.array([-0.31,0.63,0.80,0.38,-0.72,-0.69])
y2 = np.array([0.87,0.51,0.38,0.54,0.83,0.11])
y3 = np.array([0.10,0.18,-0.19,0.15,-0.16,-0.14])
#今回はsubplotで
fig, ax1 = plt.subplots()
#plotでプロット
ax1.set_ylabel('explanation of y-axis',fontname='Arial')
ax1.plot(Title,y1,marker='v',ms=11,color='orange',fillstyle='none',linestyle = 'None')
ax1.plot(Title,y2,marker='D',ms=9,color='g',fillstyle='none',linestyle = 'None')
ax1.plot(Title,y3,marker='x',ms=9,color='m',linestyle = 'None')
#軸などの微調整
ax1.tick_params(axis ='x', which ='both', top='off',bottom='off', pad=10)
plt.xticks(rotation =70)
plt.yticks([-1.0,-0.5,0,0.5,1.0])
plt.ylim(-1,1)
fig.tight_layout()
fig.savefig('FIGURE/test.png')
plt.savefig('FIGURE/'+'orig.png', bbox_inches='tight')
plt.show()
plt.clf()

という感じで、プロットはこんな感じ。

散布図

おしまい。

関連記事

1. pythonのまとめ

D

en_US English ja 日本語 zh_CN 中文

python3を使って二つの複数列テキストデータを一つにまとめる

DATA1

x y z
0 100 0.5
1 158 0.3
2 204 0.6
3 255 0.4

DATA2

x y z
1.5 178 0.1
2.5 222 0.0
3.5 301 0.1
4.0 347 0.7

こんな感じの複数列データの二つのファイルをx軸に合わせて一つのファイルに合成(マージ)って、一部界隈ではやる必要があることがある。普通はx軸がこんなシンプルじゃないし、各データの信頼性やらデータポイントの数なんかを考慮しながら混ぜる必要があったりするんだけど、今回の投稿はただ単純にくっつけるだけのもの。

importはtkinter, numpyそれからmatplotlibくらい。

tkinterで2列テキストデータをnumpyのarrayに読み込み

argvでもいいし、なんだっていいけど私はtkinterを使ってる。一応ここでは二つのデータファイルだけ読み込んで混ぜる設定。たくさん一気に混ぜたいなら、全部読み込んで混ぜるデータを間違えないように気をつけて書けばいいだけ。

tk = Tk()
tk.withdraw()
print ('select a data files')
filenames = tkfd.askopenfilenames(filetypes= [('text','*.dat'),('all','*.*')], initialdir='./DATA')
tkms.showinfo('file paths are',filenames)
tk.destroy()
data = [0]*len(filenames)
Y_RAW = [0]*len(filenames)
for i in range(len(filenames)):
  data[i] = np.loadtxt(filenames[i],comments = '*',encoding='Shift-JIS',skiprows=36)

内部リンク: pythonのtkinterを使ってユーザー入力を取得する方法

concatenateでテキストデータの重ね合わせ

numpyのconcatenateを使って各列のデータをくっつける。スケールをつける必要があるなら、どっちかのデータを単純にかけるなり、合成範囲での強度平均で割ったりすればいい。端にエラーデータを含む場合なんかは、data[1][3:-3,1]なんて感じで削る。

Mergey = np.concatenate((data[0][:,1],data[1][:,1]),axis=0)
Mergex = np.concatenate((data[0][:,0],data[1][:,0]),axis=0)
Mergez = np.concatenate((data[0][:,2],data[1][:,2]),axis=0)

swapaxesを使って元のデータ形式に戻す。こんなことしないでも直接混ぜれるかもしれないけど、書いてた時には他の方法だとうまくいかなかったんだよね。

Merge = np.swapaxes(np.vstack((Mergex,Mergey,Mergez)),0,1)

2021・1月13日追記:よくよく考えないでも、この例だったらvstackで直接混ぜれるよなっていう。なにかしらconcatenate使った理由はあったと思ったんだけど、もともとのスクリプトが見つからなかったから謎。

 Merge =np.vstack((data[0],data[1]))

X軸の並びに揃えたいなんて場合はargsortでも使って……

Merge = Merge[Merge[:,0].argsort(),:]

plotするなら……

plt.plot(Merge[:,0],Merge[:,1],ls='--')
plt.show()

saveするなら……

np.savetxt('TEXT/'+'Merged.txt',Merge)

と言う感じで混ぜれる。

 

関連記事

1. pythonのまとめ

D

en_US English ja 日本語 zh_CN 中文

【python3・覚書】よく忘れるpythonのmatplotlibの書き方一覧

よく忘れるpython3のmatplotlibの書き方の自分用の覚書。随時更新。

x軸、y軸の表記やらメモリやら色々変える

数値じゃなくてサンプル名(文字)なんかでプロットする

なぜかたまに忘れる。そのまま文字列のarrayなりリストなりをX軸にすればいい。

X1 = np.array(['a1','b1','c2','a2','c3'])

対数軸でプロット(log-log plot)

plt.xscale("log")
plt.yscale("log")

対数軸がごちゃつく場合は表示するサブメモリをsubsxで指定できる。

plt.xscale("log",subsx=[0.02,0.04,0.06,0.08])

対数軸でプロットした後にメモリの数値表記スタイルを小数点表記(0.01など)に変える

plt.gca().xaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
plt.gca().xaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter())

一応これでいけるけど、表示の微修正が必要なこともあるかも。例えば小数点単位を変えるなら同じ感じで……

plt.gca().xaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter('%.g'))

など。表記変更はsubplotを使った方が簡単に調整できそうな印象。試してないけど。

軸のメモリの表示を回転

matplotlibの設定を変える場合。

plt.xticks(rotation =70)

subplotを変えたい場合。

色々あるけど……

ax1.tick_params(labelrotation=70)

2021年1月19日追記: これだとy軸のラベルも回転するな。

ax1.tick_params('x',labelrotation=70)

これでX軸だけ回転する。

軸のメモリの有無など

tick_paramsでセット。

ax2.tick_params(axis ='x', which ='both', top='off',bottom='off', pad=10)

軸メモリを任意の場所に手動でセット

plt.xticks([0.5,3,10,12],['0.5','3','10','12'])

特殊文字やテキスト表記

文字のアウトプットの時のアポストロフィ(’)の入れ方

ax1.set_ylabel('Young\'s Modulus',fontname='Arial')
ax1.set_ylabel("Young's Modulus",fontname='Arial')

下付き文字・上付き文字

ax2.set_ylabel('r"L$_{s}$"')
ax2.set_ylabel('r"L$^{s}$"')

プロットの仕方

たくさんプロットするときの順番を指定

重ね合わせの順番が重要な時には、zorderが使える。

plt.plot(x,y,zorder=0)
plt.plot(x,y,zorder=5)

便利プロット設定

テンプレその1、よく使う、マーカー、カラー、塗りつぶし

marker = ['o','x','D','v','+']
colour = ['c','m','g','orange','b']
fill = ['none','full','none','full','none']
for i in range(num):
  data = plots[i]
  plt.plot(data[lin1:lin2,0],data[lin1:lin2,1], marker[i],color=colour[i],fillstyle=fill[i],ms=8)

テンプレその2、アルファ値、スケール、描画の順番など

def plot_raw(plots,num1,num2):
num = len(plots)
marker = ['o','x','D','v','+']
colour = ['c','m','g','orange','b']
line = ['','','','','']
linewidth = [4,4,4,4,4]
fill = ['none','none','none','none','none']
alpha = [1,1,1,1,1]
scale = [1,1,1,1,1]
ms = [8,8,8,8,8]
zorder = [5,0,10,15,20]
        for i in range(num):
                data = plots[i]
                plt.plot(data[lin1:lin2,0],data[lin1:lin2,1]/scale[i], marker[i],color=colour[i],fillstyle=fill[i],ms=ms[i],alpha=alpha[i],ls=line[i],lw=linewidth[i],zorder=zorder[i])
        return

忘れた時に随時更新の予定。更新も忘れそうだけど。

関連記事

1. pythonのまとめ

D

en_US English ja 日本語 zh_CN 中文

pythonのmatplotlibを使って3Dの棒グラフを作って書き出す

3Dグラフって見にくく感じるたちなので基本的には好きじゃないのだけど、二つの変数に対しての変化を見たい時に、代替手段がないこともある。

最初エクセルで作ろうと思ったんだけど、意外とエクセルは3Dのグラフを作るのは便利じゃなさそうな感じだった。

じゃあまあpythonか、ってことでmatplotlibで3Dグラフを作ってみた。

最初3Dのプロットを作ろうと思って調べていたら、Axes3D.barがなんとなく使えそうな感じ。

外部リンク: matplotlib公式 mplot3d tutorial

だけどこのファンクションで棒グラフを実際に作ってみると、ぺったりした薄い棒グラフであんまり綺麗じゃない。
設定で変えれないかなと色々調べたんだけど、途中でaxes3Dには最初からbar3dっていうファンクションがあることに気づく。

外部リンク: 公式 Demo of 3D bar charts

というわけで以下はこのbar3dを使って3Dの棒グラフを作る一例。

importはmatplotlibとAxes3Dくらい。

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

まずはいつも通り、最初に適当に描画設定をする。

plt.rcParams['font.family']='Arial'
plt.rcParams['font.size']= 14
plt.rcParams['axes.linewidth']=2.5
plt.rcParams['xtick.major.width']=2.5
plt.rcParams['xtick.labelsize']=14
plt.rcParams['ytick.major.width']=2.5
plt.rcParams['ytick.labelsize']=14
plt.rcParams['figure.figsize']=(8,6)

続いて適当にX軸とY軸を設定。同じYの値に二つのデータを突っ込んで見たくてこんな感じの値を与えてみた。
多分もっといい書き方があるはずだけど、まあpyhtonは動けばいいんだよ派なので気にしない。

X = np.array([0,0.5,1,2,3])
Y1 = np.array([1.12])
Y2 = np.array([2.12])
Y3 = np.array([3.12])
Y4 = np.array([0.88])
Y5 = np.array([1.88])
Y6 = np.array([2.88])

続けてZ軸のスタートポジションを設定。
ちょっとデータを入れたくないポジションがあって、スタートポジション外して消してたんだけど、これももっといい消し方があるんと違うかな。でも動けばいいんだよ派なので……(略

Z0 = np.array([-1020,0,0,0,0])
Z01 = np.array([-1020,-1020,0,0,0])
Z = np.array([0,0,0,0,0])

続いてZ軸の高さの値を設定。

Z1 = np.array([0,19,12,8,7])
Z2 = np.array([16,9,8,6,5])
Z3 = np.array([9,8,6,5,4])
Z4 = np.array([0,0,26,16,13])
Z5 = np.array([29,14,16,12,11])
Z6 = np.array([15,16,12,5,8])

様式美からデータのプロットへ。dx,dzで棒グラフの形を決めて、dzは棒グラフの高さ。
そうそう、特定条件のpythonやら何やら使ってると、アルファ値設定しても透明にならないバグがある。
一応修正できるっぽかったけど、直すの結構面倒くさそうだったのでスキップ。そもそもpythonかmatplotlibのバージョン変えれば直るんじゃないかな。

fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.bar3d(X,Y4,Z01,dx=0.19,dy=0.2,dz=Z4,shade=True)
ax.bar3d(X,Y5,Z,dx=0.19,dy=0.2,dz=Z5,shade=True)
ax.bar3d(X,Y6,Z,dx=0.19,dy=0.2,dz=Z6,shade=True)
ax.bar3d(X,Y1,Z0,dx=0.19,dy=0.2,dz=Z1,shade=True)
ax.bar3d(X,Y2,Z,dx=0.19,dy=0.2,dz=Z2,shade=True)
ax.bar3d(X,Y3,Z,dx=0.19,dy=0.2,dz=Z3,shade=True)

続けて軸やら表示の微調整。

ax.set_yticks([1,2,3])
ax.set_xticks([0,1,2,3])
ax.set_xlabel('condition1')
ax.set_ylabel('condition2')
plt.xlim(0,3)
plt.ylim(3.5,0.5)
ax.set_zlim(0,50)

最後に絵をセーブして、見せておしまい。

plt.savefig('FIGURE/'+'orig.png', bbox_inches='tight')
plt.show()

でグラフはこんな感じになる。

3Dバーの例

まあそんなに見やすくもないけど、なんとなく雰囲気は掴める3D棒グラフになりました。

最後はうちのKatja。

Katjaのご尊顔

棚の上に落ち着いたKatja

メリークリスマス!

関連記事

1. pythonのまとめ

D

en_US English ja 日本語 zh_CN 中文

pythonのmatplotlibで縦軸二つの散布図を作って書き出す

久々にpython投稿。

ちょっと論文を書くのにy軸二つ並べて、モデルから計算した値と実験値を並べたかったので、pythonで描写。

シンプルに公式ホームページの通りに書いていけば問題はないと思う。

外部リンク: Plots with different scales

importはmatplotlibの設定くらい。

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

まずは適当に好みの図の描写設定。

plt.rcParams['font.family']='Arial'
plt.rcParams['font.size']= 14
plt.rcParams['axes.linewidth']=2.5
plt.rcParams['xtick.major.width']=2.5
plt.rcParams['xtick.labelsize']=14
plt.rcParams['ytick.major.width']=2.5
plt.rcParams['ytick.labelsize']=14
plt.rcParams['figure.figsize']=(3,4)

それから適当にプロットするモデルのデータ。

X1 = np.array([-0.5])
SLD1 = np.array([15.8])
SLD2 = np.array([6.25])
SLD3 = np.array([11.53])
SLD4 = np.array([2.9])

いつもの。

fig, ax1 = plt.subplots()

ガスガス1軸目をプロット。それから目盛りのサイズやらラベルやらの調整。

ax1.plot(X1,SLD1,marker='v',ms=11,color='orange',fillstyle='none')
ax1.plot(X1,SLD2,marker='D',ms=9,color='g',fillstyle='none')
ax1.plot(X1,SLD3,marker='x',ms=9,color='m')
ax1.plot(X1,SLD4,marker='+',ms=9,color='b')
ax1.tick_params(axis ='x', which ='both', top='off',bottom='off', pad=10)
ax1.set_xticklabels([])
ax1.set_ylabel(r"$\Delta$"+'SLD$^{2}$'+'x'+'10$^{20}$'+ ' [cm$^{-2}$]',fontname='Arial')
ax1.set_ylim(0,20)

2軸目追加。

ax2 = ax1.twinx()

2軸目用の実験データ。

X2 = np.array([0.5])
I1 = np.array([388])
I2 = np.array([187])
I3 = np.array([313])
I4 = np.array([35])

2軸目データのプロットと軸のメモリとラベルの設定。

ax2.plot(X2,I1,marker='v',ms=11,color='orange',fillstyle='none')
ax2.plot(X2,I2,marker='D',ms=9,color='g',fillstyle='none')
ax2.plot(X2,I3,marker='x',ms=9,color='m')
ax2.plot(X2,I4,marker='+',ms=9,color='b')
ax2.tick_params(axis ='x', which ='both', top='off',bottom='off', pad=10)
ax2.set_xticklabels([])
plt.xlim(-1,1)
ax2.set_ylabel('INT [cm$^{-1}$]')
ax2.set_ylim(0,400)

最後に絵を出力。figを使っても使わなくても出力は変わんない?

fig.tight_layout()
fig.savefig('FIGURE/test1.png', bbox_inches='tight')
plt.savefig('FIGURE/test2.png', bbox_inches='tight')
plt.show()

絵はこんな感じ。

y2軸のプロット

というわけで、そんなにスケールがあってなかったよ、という絵。

関連記事

1. pythonのまとめ

D