これは難しい
グラフ
基本
◎プロットする(簡易)
from matplotlib import pylab as plt
plt.plot(X,Y)
plt.xlim([x0,x1])#範囲を指定
plt.ylim([y0,y1])
plt.xscale('log')#log scaleにする(こいつらいっぺんに指定できんのか?)
plt.yscale('log')
◎基本フォーマット(論文用:Fig>Axes>Axisらしい )
from matplotlib import pylab as plt
fig, ax = plt.subplots(figsize=(4,3))#fig, axを同時に作っているらしい
plt.rcParams['font.family'] = 'Times New Roman' #フォントを変える
plt.rcParams['mathtext.fontset'] = 'stix' #フォントを変える2
ax.tick_params(axis="both",which="both",direction="in", top = True, right=True) #ticsを上下両サイド内側にする
ax.set_title("TITLE") #タイトル
ax.set_xlim(x0,y0) #x軸の範囲設定
ax.set_xscale("log") #x軸をlog scaleに
ax.set_xlabel("XXX",fontsize=1)#ラベルをつける
ax.plot(X,Y)
ax.legend(loc=2,labelspacing=0.1)#loc=(1,2,3,4)=(右上,左上,左下,右下)
fig.savefig("fig_FIGURE.pdf", bbox_inches='tight') #pdfに保存する
◎字を書く
ax.text(x0,y0,"XXX",color="black",fontsize=10,rotation=0)
◎TEXみたいに数式を打ちたい
ax.text(x0,y0,"\\alpha")#\\と重ねるのがポイント
◎点を打つ
ax.plot([x0,x1,...],[y0,y1,...],ls="",marker="o",ms=1,mew=0.5,mec="black")#ms=markersize,mew=markeredgewidth,etc...,scatterとの違いもよくわからん
◎矢印を引く
ax.annotate("XXX",[x0,y0],[x1,y1],arrowprops=dict(width=5,headwidth=15,headlength=10,facecolor="red",edgecolor="black"))
ax.annotate("XXX",[x0,y0],[x1,y1],arrowprops=dict(arrostyle="<|-|>",color="black"))#両矢印(あまりフレキシブルでない)
◎塗りつぶし
ax.fill_between(X,Y1,Y2,color="red",alpha=0.5)#2つのグラフの間を塗る
ax.fill([x0,x1,x2],[y0,y1,y2],color="red",alpha=0.5)#よりフレキシブル
◎エラーバー付きのプロット
ax.errorbar(X,Y,xerr=[Xlow,Xhigh],yerr=[Ylow,Yhigh],fmt="o",makersize=1,capsize=1,ecolor="red",markeredgecolor="red")#Xlowとかはエラー幅
◎余白調整
plt.subplots_adjust(left=0.1,right=0.9,bottom=0.1,top=0.9)#数字の意味は知らん
◎gridを引く(これも未知)
ax.grid(which = "major", axis = "both", color = "black", alpha = 0.5, linestyle = "--", linewidth = 1)
ax.grid(which = "major", axis = "y", color = "black", alpha = 0.5, linestyle = "--", linewidth = 1)
◎軸をふたつ設定する
secax = ax.secondary_yaxis('right', functions=(lambda x: x**2, lambda x: np.sqrt(x))#右側の軸をy**2で設定する(functionsは函数と逆関数)
secax.tick_params(axis="both",which="both",direction="in", top = True, right=True)#目盛を内部にする
secax.set_ylabel("",fontsize=12)
◎Legendを複数にわける
from matplotlib.pyplot import *
PLOT[i] = ax.plot(X,Y,label=LABEL[i])
legend1 = ax.legend(PLOT[i],LABEL[i])
gca().add_artist(legend1)#最後のやつ以外はこうしないと反映されない
◎Legendを外に設置する
ax.legend(loc=1,bbox_to_anchor=(1.,1.0275))#数字の意味はわからん
◎Legendの順序を自由に設定する(errorbarとplotだとplotが優先されるので)
handles,labels = ax.get_legend_handles_labels()#使い方はよくわからんがlist番号とplotなどの対応を意識する
handles = [handles[2], handles[3], handles[0], handles[1]]
labels = [labels[2], labels[3], labels[0], labels[1]]
ax.legend(handles,labels,loc=1,labelspacing=0.1)
目盛あれこれ
◎目盛(major tick)を任意に設定する
ax.set_xticks([X0,X1,X2,...])
◎目盛数値を消す
ax.axes.xaxis.set_ticks([])
◎目盛を任意の感覚で設定する
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
ax.xaxis.set_major_locator(MultipleLocator(5))#大目盛:dx=5
ax.xaxis.set_minor_locator(MultipleLocator(1))#小目盛:dx=1
◎対数目盛(major and minor tick)を任意に設定する
import matplotlib.ticker
ax.xaxis.set_major_locator(matplotlib.ticker.LogLocator(base=10,numticks=10))#major tickを設置する(mojorの場合は上でもOK)
ax.xaxis.set_minor_locator(matplotlib.ticker.LogLocator(base=10,subs=(2,3,4,5,6,7,8,9),numticks=10))#minor tickを2,...,9まで設置する
ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())#minor tickにはなぜか必要
◎目盛の書式を(1x10から10とかにする:対数)
import matplotlib
ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
◎さらに小数点などを変更したい(0.1,1.0,10.0から0.1,1,10とかにする)
import matplotlib.ticker as ticker
def major_formatter(x, pos):
if y<1:
return x
else:
return "%.0f" % x
ax.yaxis.set_major_formatter(ticker.FuncFormatter(major_formatter))
ax.set_yticks([0.1,1,10])
色
◎グラデーション(数値に対応して配色する)
import matplotlib.cm as cm
Color = cm.XXX(value) #XXX:hsv,jetなど、value:数値
◎12色(冠位十二階:あまり見栄えはよくない)
COLOR = ["purple","royalblue","blue","dodgerblue","red","pink","yellow","khaki","white","gainsboro","black","gray"]
ヒストグラム
◎ヒストグラムを描く(logの場合、予めx-axisをlogscaleにしておく)
ax.hist(X,bins=np.logspace(-1,1,21),histtype="bar")
◎ヒストグラム付き散布図を描く
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots(figsize=(4,4))#以降で普通に散布図を描く
divider = make_axes_locatable(ax)#これでaxに追加で図を書くようにしているらしい
axHistx = divider.append_axes("top", 0.5, pad=0.)
axHisty = divider.append_axes("right", 0.5, pad=0.)#以降でヒストグラムをaxのように書いていけばいい
axHistx.hist(X,bins=(X0,X1,10),color="red")
axHisty.hist(Y,bins=(Y0,Y1,10),color="red",orientation='horizontal')
分布図(density plot)
◎density plotの基本((x,y,z)でz場をプロットする)
X,Y = np.meshgrid(x,y)#これちゃんとやる
cs = ax.contourf(x,y,z,levels=[z0,z1,z2,...],cmap=cm.viridis)
cbar = fig.colorbar(cs,aspect=30,pad=0.03)#color barをつける
cbar.ax.set_ylabel(Z)#color barのラベルをつける
複数の図をつくる1(上下2段のみ)
fig, axes = plt.subplots(2,1,figsize=(4,3))
◎サイズ(比)を変更したいとき
fig, axes = plt.subplots(2,1,gridspec_kw={"height_ratios":[1,3]},figsize=(4,3))
#縦(横の場合は"width_ratios"))
◎x軸を共通にする
fig, axes = plt.subplots(2,1,figsize=(4,3),sharex=True)
◎上下の図の間隔(spacing)を変更
plt.subplots_adjust(hspace=0)#完全にくっつける場合
複数の図をつくる2(ほんまにいっぱい)
◎大量の図をつくる(MxN個並べてまとめて処理する場合)
fig, axes = plt.subplots(M,N,figsize=(1,1))
for i in range (M):
for j in range (N):
axes[i][j].plot(X,Y)
◎図の数がちょうどいいときじゃないとき
axes[i][j].axis("off")
◎各図のylabelの位置をそろえる
fig.align_labels([axes[0],axes[1],...])
◎Loopとtex式の両立(今までlabel=f"X={XXX[i]}"とかでやってたから添字とかつけられんかった)
axes[i].set_title("$X_{i}=$%f" %(XXX[i]))#とすりゃいい
◎共通のタイトルをつける
fig.suptitle
媒介変数によって色が変化する曲線を描く((x(t),y(t))をtによって色を変える=>x,yを区切って大量の短いグラフとする)
#ax=plt.XXXとかやっておく
import matplotlib.cm as cm
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
norm = plt.Normalize(t.min(), t.max())#色付するために媒介変数tで規格化する
lc = LineCollection(segments, cmap='jet', norm=norm)
lc.set_array(dydx)
lc.set_linewidth(5)
line = ax.add_collection(lc)
fig.colorbar(line, ax=ax)
出力
◎変数を文字列に埋め込む方法
n=1
print("{}".format(n))
◎数値の書式を指定する方法(.1f=小数第一位,.1e=同じく(1.1e+10),.1g=1桁まで)
m=1.1
n=1.1
print("m={0:.1f},n={1:.1e}".format(m,n)
◎数値Xを有効数字N桁で四捨五入して整数値で出力する(もっといい方法ありそう)
Str = str(int(X))#文字列に変換
Len = int(len(Str)-1)#桁数を得る
X = int(round(X/10**Len,N-1)*10**Len)
計算
◎求根(函数f(x)=0の解を[x1,x2]の範囲で探す)
from scipy import optimize
para = (X,Y,...) #f(x)の他の引数があるとき
optimize.brentq(f, x1, x2, args=para)
◎ODEを解く(dX/dt=f(X,t))
from scipy.integrate import odeint
def ODE(X,t)
X0 = X[0]
X1 = X[1]
dX0dt = f0(X0,X1,t)
dX1dt = f1(X0,X1,t)
return [dX0dt,dX1dt]
IC = [X0_ini,X1_ini] #初期値
time = np.linspace(t0,t1,100) #時間[t0,t1]を100分割して積分
y=odeint(ODE,IC,time,args=para).T #parameterがあるとき最後いる
◎ODEを解く2(dY/dt=F(Y,t):こっちの方が最新らしい)
from scipy.integrate import solve_ivp
def ODE(t,Y,a)
Y0 = Y[0]
Y1 = Y[1]
dY0dt = F0(Y0,Y1,t)
dY1dt = F1(Y0,Y1,t)
return [dY0dt,dY1dt]
IC = [Y0_ini,Y1_ini] #初期値
time = np.linspace(t0,t1,N)
SOL = solve_ivp(lambda t,y:ODE(t,y,a),[time[0],time[-1]],IC,t_eval=list(time))#ODEにparameterがないときはlambdaはいらん
t = SOL.t
Y0 = SOL.y[0]
Y1 = SOL.y[1]
◎内挿(1次元:x_data,y_dataを内挿する)
from scipy import interpolate
y_int = interpolate.interp1d(x_data, y_data)#線形内挿
y_int = interpolate.interp1d(x_data, y_data,kind="cubic")#三次関数
◎最小化(函数fをparameter(a,b)のもとで最小化する
import scipy
from scipy import optimize
bounds = ((a0,a1),(b0,b1))
result = scipy.optimize.brute(f,ranges=bounds,Ns=20)
a,b = result
◎微分(函数F(x)の導関数のx=x0での値)
from scipy.misc import derivative
dfdx = derivative(F,x0,dx=1.e-10)
◎積分(函数F(x)を区間[x0,x1]で積分する)
from scipy import integrate
integrate.quad(F,x0,x1)[0]
◎重積分(函数F(y,x)を区間[y0=f0(x),y1=f1(x)],[x0,x1]で積分する(yを先に積分する)
integrate.dblquad(F,x0,x1,lambda x:f0(x),lambda x:f1(x),args=(a,b))#よくわからんけどparameterは2つ以上ないと走らない
◎特殊函数
#ガンマ函数 Gamma(x)[gamma(x)]
from scipy.special import gamma
#第二種変形ベッセル函数 K_v(x)[kv(v,x)]
from scipy.special import kv
np.arrayあれこれ
import numpy as np
◎要素の削除
X=np.array([0,1,2,3])
X_new=np.delete(X,0)#0行目が消える
◎要素の削除2
X=np.array([0,1,2],[3,4,5],[6,7,8])#各々arrayとする
X_new=np.delete(X,0,0)#とかで便利に消せる
◎要素数などを調べる
print(Z.shape)
◎要素の順番を逆転させる
X[::-1]
◎要素成分の和をとる
np.sum(X)
np.sum(X[0:i]) #0~i番目の成分だけ和をとる
◎npを自作函数F(x)の独立変数にして従属変数もnpにする
Y = np.array([F(x) for x in X])
◎np Xにnp Yを結合してnp Zにする
Z = np.append(X,Y)
◎np Xが極値を取る配列の番号を調べる
from scipy import signal
n_exe = signal.argrelmin(X) #極小
n_exe = signal.argrelmax(X) #極大
◎転置
X = X.T
ファイルの操作
◎読み込み(文字列がないとき)
X = []
with open("XXX.txt") as f:
next(f)#ヘッダー(1行目)飛ばす
for line in f:
line = list(map(float,line.split())
X.append(line[0])
◎読み込み(文字列があるとき)
X=[]
with open("XXX.txt") as f:
for line in f:
name = line.split()[0]#1行目が天体名の設定
del line[0]
line = list(map.float,line.split())#以下同じ
◎書き込み
data = np.array([X,Y,...]).T
np.savetxt("FILENAME.txt",data,fmt="%s")
統計
◎平均、中央値、(標本)分散、標準偏差
import statistics as sta
X=np.array([0,1,...])
mean = sta.mean(X)
median = sta.median(X)
variance = sta.pvariance(X)
standard_deviation = sta.pstdev(X)
◎パラメータ推定とその信頼区間(モデル関数F(x;a1,...,an)でデータ(xi,yi)をフィットし、パラメータの信頼区間を推定)
def Error(var,*arg):###calcluate chi^2 for a given t0 (variable) and v (parameter)
a1,...,an = var
a0, www = arg #www is dammy
Y = F(xi,a0,...,an)
return np.sum(((yi-Y)/dyi)**2)
def Error2(a0):#minimize chi^2 for a given a0
bounds = ((a1_1,a1_2),...,(an_1,an_2))
Para = scipy.optimize.brute(Error,ranges=bounds,args=(a0,0),Ns=20)
return Error(Para,a0,0)-chi_min
FUNC = lambda a0 : Error2(a0)-1 #dchi^2=1で63.8%の信頼区間を1parameterについて求める
a0_error=optimize.brentq(FUNC, a0_best, a0_best + 0.1*np.abs(a0_best))
a0_error2=optimize.brentq(FUNC, a0_best - 0.1*np.abs(a0_best), a0_best)
その他の便利な操作
◎変数の型を判定する
isinsrance(X,float)#XがfloatならTrueを返す(分岐に使える)
◎数字を文字列に変換する
ii = "%03d" % i#iを3桁の文字列iiに変換する(ファイルの操作に使える)
◎函数を簡略化して定義する
F = lambda x,y:x**2+y**2
◎for loopを複数の変数(変数の組で回す)
x = [x0,x1,x2]
y = [y0,y1,y2]
for i,j in zip(x,y):
print(i,j)
◎現在時刻を知る
import datetime
print(datetime.datetime.now())
◎複数のlistを同時にnp.arrayに変換
X,Y,Z,...=map(np.array,[X,Y,Z,...])