これは難しい
グラフ
基本
◎プロットする(簡易)
 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,...])