cms.smoothing.smoothing のソースコード

import csv
import matplotlib.pyplot as plt

"""
このスクリプトは、異なる手法とパラメータを使用してデータを平滑化します。
:doc:`smoothing_usage`

詳細説明:
指定されたCSVファイルから実験データを読み込み、X軸の範囲でデータをフィルタリングします。
その後、単純移動平均法と多項式近似(Savitzky-Golayフィルターに類似)の2つの異なる平滑化手法を、複数の窓幅で適用します。
平滑化されたデータは個別のCSVファイルに保存され、元のデータと平滑化されたデータがmatplotlibによってグラフとして可視化されます。
"""


#=============================
# parameters
#=============================
csvfile = 'xrd.csv'
outfile_template = 'smoothing-{}-{}.csv'
xmin = 37.0
xmax = 46.0


[ドキュメント] def SmoothingBySimpleAverage(y, n): """ 移動平均法を用いてデータを平滑化します。 詳細説明: 指定された窓幅 `n` の前後 `n/2` の範囲にある点の平均値を計算し、各点の新しい値とします。 データ範囲の端では、利用可能な点のみで平均が計算されます。 :param y: list: 平滑化する元のY座標データ(数値のリスト)。 :param n: int: 平滑化に使用する窓幅。内部で `int(n/2)` が使用されるため、奇数、偶数いずれの場合も中央の前後で対称的な窓が形成されます。 :returns: list: 平滑化されたY座標データのリスト。 """ n2 = int(n / 2); ndata = len(y); ys = [] for i in range(0, ndata): c = 0; ys.append(0.0); for k in range(i - n2, i + n2 + 1): if k < 0 or k >= ndata: continue ys[i] += y[k] c += 1 if c > 0: ys[i] /= c; else: ys[i] = y[i] return ys;
[ドキュメント] def SmoothingByPolynomialFit(y, n): """ 多項式近似(Savitzky-Golayフィルターに類似)を用いてデータを平滑化します。 詳細説明: 指定された窓幅 `n` の範囲にあるデータポイントに重み付き多項式近似を適用してデータを平滑化します。 使用される重み `w23j` は、Savitzky-Golayフィルターの二次多項式、三次フィットに似た係数計算に基づいており、 中央の点ほど大きな重みが与えられます。データ範囲の端では、利用可能な点のみで計算が行われます。 :param y: list: 平滑化する元のY座標データ(数値のリスト)。 :param n: int: 平滑化に使用する窓幅。内部で `int(n/2)` が使用されるため、奇数、偶数いずれの場合も中央の前後で対称的な窓が形成されます。 :returns: list: 平滑化されたY座標データのリスト。 """ m = int(n / 2); W23 = (4.0 * m * m - 1.0) * (2.0 * m + 3.0) / 3.0; w23j = [0.0]*n for j in range(-m, m+1): w23j[j + m] = (3.0 * m * (m+1.0) - 1.0 - 5.0 * j * j) / W23 ndata = len(y) ys = [] for i in range(0, ndata): c = 0.0; ys.append(0.0); for j in range(-m, m+1): k = i + j if k < 0 or k >= ndata: continue ys[i] += w23j[j+m] * y[k] c += w23j[j+m] if c > 0: ys[i] /= c else: ys[i] = y[i] return ys;
[ドキュメント] def savecsv(outfile, x, y, ys): """ データをCSVファイルに保存します。 詳細説明: 指定されたファイル名でCSVファイルを開き、X軸データ、元のY軸データ、および平滑化されたY軸データを 'x', 'y(raw)', 'y(smooth)' のヘッダーと共に保存します。 ファイルへの書き込み中にエラーが発生した場合は、コンソールにエラーメッセージを出力します。 :param outfile: str: 出力するCSVファイルのパスとファイル名。 :param x: list: X座標データのリスト。 :param y: list: 元のY座標データのリスト。 :param ys: list: 平滑化されたY座標データのリスト。 :returns: None """ try: print("Write to [{}]".format(outfile)) f = open(outfile, 'w') except: # except IOError: print("Error: Can not write to [{}]".format(outfile)) else: fout = csv.writer(f, lineterminator='\n') fout.writerow(('x', 'y(raw)', 'y(smooth)')) # fout.writerows(data) for i in range(0, len(x)): fout.writerow((x[i], y[i], ys[i])) f.close()
[ドキュメント] def main(): """ スクリプトのメイン処理を実行します。 詳細説明: - グローバル変数 `csvfile` で指定されたCSVファイルからデータを読み込みます。 - `xmin` と `xmax` で指定された範囲外のデータは除外します。 - 異なる窓幅で単純移動平均法による平滑化を適用し、結果をCSVファイルに保存し、グラフにプロットします。 - 異なる窓幅で多項式近似法による平滑化を適用し、結果をCSVファイルに保存し、グラフにプロットします。 - 全ての平滑化結果を一つのフィギュア内のサブプロットに表示し、ユーザーの入力があるまで待機します。 :returns: None """ global csvfile global outfile print("Read data from [{}]".format(csvfile)) x = [] y = [] with open(csvfile) as f: fin = csv.reader(f) next(fin) c = 0 for row in fin: if c == 0: label = row print("{}\t{}".format(label[0], label[1])) else: xx = float(row[0]) yy = float(row[1]) if xx < xmin or xmax < xx: continue print("{}\t{}".format(row[0], row[1])) x.append(xx) y.append(yy) c += 1 ndata = len(x) print("") #============================= # prepare graph #============================= fig, ax = plt.subplots(3, 3, figsize = (8, 8)) ys = [] print("Smoothing by simple moving average") icase = 0 nsmooth = 3; method = 'simple' print("nsmooth={}".format(nsmooth)) ys.append(SmoothingBySimpleAverage(y, nsmooth)) for i in range(0, ndata): print("{}\t{}\t{}".format(x[i], y[i], ys[icase][i])) savecsv(outfile_template.format(method, nsmooth), x, y, ys[icase]) print("") ax[0, 0].plot(x, ys[0], label = "{}p {}".format(nsmooth, method), linewidth = 0.5) ax[0, 0].plot(x, y, linestyle = 'none', marker = 'o', markersize = 0.3) ax[0, 0].set_title("{}p {}".format(nsmooth, method)) icase = 1 nsmooth = 11; method = 'simple' print("nsmooth={}".format(nsmooth)) ys.append(SmoothingBySimpleAverage(y, nsmooth)) for i in range(0, ndata): print("{}\t{}\t{}".format(x[i], y[i], ys[icase][i])) savecsv(outfile_template.format(method, nsmooth), x, y, ys[icase]) print("") # ax[0, 1].plot(x, y, linestyle = 'none', marker = 'o', markersize = 0.5) ax[0, 1].plot(x, ys[1], label = "{}p {}".format(nsmooth, method), linewidth = 0.5) ax[0, 1].set_title("{}p {}".format(nsmooth, method)) icase = 2 nsmooth = 31; method = 'simple' print("nsmooth={}".format(nsmooth)) ys.append(SmoothingBySimpleAverage(y, nsmooth)) for i in range(0, ndata): print("{}\t{}\t{}".format(x[i], y[i], ys[icase][i])) savecsv(outfile_template.format(method, nsmooth), x, y, ys[icase]) print("") # ax[0, 2].plot(x, y, linestyle = 'none', marker = 'o', markersize = 0.5) ax[0, 2].plot(x, ys[2], label = "{}p {}".format(nsmooth, method), linewidth = 0.5) ax[0, 2].set_title("{}p {}".format(nsmooth, method)) icase = 3 nsmooth = 51; method = 'simple' print("nsmooth={}".format(nsmooth)) ys.append(SmoothingBySimpleAverage(y, nsmooth)) for i in range(0, ndata): print("{}\t{}\t{}".format(x[i], y[i], ys[icase][i])) savecsv(outfile_template.format(method, nsmooth), x, y, ys[icase]) print("") # ax[1, 0].plot(x, y, linestyle = 'none', marker = 'o', markersize = 0.5) ax[1, 0].plot(x, ys[3], label = "{}p {}".format(nsmooth, method), linewidth = 0.5) ax[1, 0].set_title("{}p {}".format(nsmooth, method)) print("Smoothing by polynomial fit") icase = 4 nsmooth = 11; method = 'polynomialfit' print("nsmooth={}".format(nsmooth)) ys.append(SmoothingByPolynomialFit(y, nsmooth)) for i in range(0, ndata): print("{}\t{}\t{}".format(x[i], y[i], ys[icase][i])) savecsv(outfile_template.format(method, nsmooth), x, y, ys[icase]) print("") # ax[1, 1].plot(x, y, linestyle = 'none', marker = 'o', markersize = 0.5) ax[1, 1].plot(x, ys[4], label = "{}p {}".format(nsmooth, method), linewidth = 0.5) ax[1, 1].set_title("{}p {}".format(nsmooth, method)) icase = 5 nsmooth = 31; method = 'polynomialfit' print("nsmooth={}".format(nsmooth)) ys.append(SmoothingByPolynomialFit(y, nsmooth)) for i in range(0, ndata): print("{}\t{}\t{}".format(x[i], y[i], ys[icase][i])) savecsv(outfile_template.format(method, nsmooth), x, y, ys[icase]) print("") # ax[1, 2].plot(x, y, linestyle = 'none', marker = 'o', markersize = 0.5) ax[1, 2].plot(x, ys[5], label = "{}p {}".format(nsmooth, method), linewidth = 0.5) ax[1, 2].set_title("{}p {}".format(nsmooth, method)) icase = 6 nsmooth = 51; method = 'polynomialfit' print("nsmooth={}".format(nsmooth)) ys.append(SmoothingByPolynomialFit(y, nsmooth)) for i in range(0, ndata): print("{}\t{}\t{}".format(x[i], y[i], ys[icase][i])) savecsv(outfile_template.format(method, nsmooth), x, y, ys[icase]) print("") # ax[2, 0].plot(x, y, linestyle = 'none', marker = 'o', markersize = 0.5) ax[2, 0].plot(x, ys[6], label = "{}p {}".format(nsmooth, method), linewidth = 0.5) ax[2, 0].set_title("{}p {}".format(nsmooth, method)) plt.tight_layout() plt.pause(0.1) print("Press ENTER to exit>>", end = '') input() exit()
if __name__ == '__main__': main()