数値を表にまとめてグラフにしてってソフトウエアは何が良いのだろうねー?

 

特に私から何か答えがあるわけでもないのだけど、なんとなくの雑記。

テーブルというか数値データをシェアするのにはエクセル使うことが多いんだけど、その理由はまあエクセル使ってる人が多いからってのが主なところ。「タブか空白区切りのテキスト送ってっ!」って人もいるけれど、まあエクセルにしてくれって言われることも結構多いわけだ。

良かれ悪かれデータをエクセルでシェアしてるんだから、そのままグラフもエクセルでアウトプットできれば良いんだけど、大概の場合エクセル出力の図でハッピーになってくれる研究者は少ないのも事実……見てわかればいいじゃん、と思わないではないけど。

 

ってなわけでグラフ作るには何かしら別のソフトで、ってことになることが多いよね。

つかったことある有償ソフトだとIgor。Igorはデータプロセスのソフトとか書けたりするから、その絡みでつかってるって人が多い。それからmatlabなんかで同様の理由で結構使われてて、出力スタイルまで整えたスクリプトを持ってるって人も結構いる。でも、この辺のソフトは結構良い値段がする。

つかったこと無いけどOriginもよく使われてるよね。値段は知らないけど。

 

んでまあ元貧乏研究者としてはフリーソフトでどうにかしたかったところなわけだけど……そうなるとgnuplotあたりが筆頭かしらね?

Gnuplotはテキストデータなんかがあるときにプロット作るにはとても足回りが良いのだよね。装置の出力データなんかをとりあえずプロットするときはだいたいgnuplotをつかっていた。

それなりに絵を整えることもまあできるので、gnuplotで書いた絵を発表用に使うことはまあ可能。

 

あとはPythonとかつかってもいいんだけど……こっちもアウトプットの体裁を整えるのは割と簡単なんだけど、エクセルからデータの読み込みってなるとpandas当たりでちょこちょこ書く必要がある。

同じスタイルのエクセルがたくさんあってデータを読み込んでプロット、って言うならPythonも悪くないんだけど、違ったデータスタイルに合わせてちょいちょい書き直す必要があったりするとトタンに面倒くさくなったりするのだよな。

んー、pandasでデータ読み込むってところの処理をちょっと便利にできるようなテンプレを書いておくといいのかなー。

 

まあ結局何つかっても大して変わらない印象だけど、「利便性もビジュアルもこれが最高っ!」みたいな新しいソフトとかはあるのかしらねえ?

 

D

 

macでプログラムとか書いている時によく使うターミナルコマンドなど

 

プログラムをターミナルのviで書いてる時なんかによく使うコマンドなどを書いていく投稿。

macのターミナルのコマンド関連

terminalで現在いるディレクトリをファインダーで開く

openにピリオド

open .

ファインダーで開いてるディレクトリにterminalで移動

コマンドラインにcdをタイプしてから、ファインダーの中のフォルダをドラッグしてターミナルの上にドロップ。

コマンドラインからZipにフォルダーを圧縮

単純に圧縮するだけってのがしたいのにいつも忘れるコマンド。変なオプションつけてパスワード付きになっちゃったりするんだよな。

ともかく、これだけで良い。

zip -r AnyName.zip FolderName

terminalからファイルの拡張子をまとめて変える

for filename in ./*; do mv $filename ${filename%}.txt; done

これってシェルスクリプトってやつなの? 詳しくないからわからないんだけど、まあ動いてるからヨシッ。

terminalからファイル、フォルダのサイズチェック

du -sh (filename/foldername)

 

その他mac使うのに便利な操作

macのファインダーで隠しファイルを出したい場合

[command]+[shift]+[.]

これだけ。

タブブラウザの閉じたタブを復元

[command] + [shift] + [t]

macというかブラウザだけど。

 

 

何かあれば随時追記予定。

 

 

関連記事

1. python・科学関連記事のまとめ

D

python3でnumpyのarrayを逆順で読み込み

いつも忘れるので自分用メモ。xy座標で0から-1と0から1を分けて処理したいとか言ったときに、座標を逆順から読み込む方法。以下はnumpyのarrayで。

numpyのarrayを逆順で読み込み

スライスかnumpyのflipを使う

端っこから逆順。スライスを使った場合。スライスを使う場合には、場所指定の数がずれることにだけ注意が必要。

print (Qhor[0:10])
print (Qhor[9::-1])
print (np.flip(Qhor[0:10],axis=0))

出力

[0. 0. 0. 0. 0. 0. 921.18257197 907.22434369 907.54839177 917.00774199]
[917.00774199 907.54839177 907.22434369 921.18257197 0. 0.  0. 0. 0. 0. ]
[917.00774199 907.54839177 907.22434369 921.18257197 0. 0. 0. 0. 0.  0.]

ちょっと見にくいので真ん中を切り出したバージョン。

print (Qhor[20:25])
print (Qhor[24:19:-1])
print (np.flip(Qhor[20:25],axis=0))

出力

[958.26422151 958.88673711 958.01356441 960.51771837 965.83001593]
[965.83001593 960.51771837 958.01356441 958.88673711 958.26422151]
[965.83001593 960.51771837 958.01356441 958.88673711 958.26422151]

おしまい。

関連記事

1. pythonのまとめ

 

 

[python3・覚書] よく忘れるpython3の書き方・一般編

よく忘れるpython3の書き方の覚書。

1行が長い場合に途中で改行が入れたい場合

バックスラッシュが使える。

df = pd.DataFrame(data=[np.round(dat1,1)\
np.round(dat2,1),\
np.round(dat3,1)],\
columns=basename,index=['dat1','dat2','dat3'])

読み込んだファイルの名前情報を取得する

tkinterで読み込んでる場合

filenames = tkfd.askopenfilenames(filetypes= [('text','*.xy'),('text','*.ras')], initialdir='./DATA')
for i in range(len(filenames)):
  basename[i] = os.path.basename(filenames[i])

numpyのarrayデータをprintする時省略せずに全部見せる

import numpy as np
import sys
np.set_printoptions(threshold=sys.maxsize)

 

 

随時更新

 

関連記事

1. pythonのまとめ

D

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

 

 

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しか見つからない。んー、どうなってるんだろ。

2021/05/03追記:

Catalinaで違うPythonプログラム(pyFAI)を使ってたら似たようなエラーをくらったので追記。

上記のexportでは解決せず。というかこれはcatalinaの問題ではなく、プログラムの方のopenclの使い方の問題。

解決方法はpyopenclをUninstallして、macOSのOpenCLが使われるようにしただけで問題なく動いた。

どのOpenCL使うか指定するのでも良いかもしれないけど、やり方がわからなかったのでアンインストした。どこかで他のプログラムが動かなくなる予感はあるが。

D

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

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

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

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