本記事では、下図のように2つのデータを重ね合わせる雛形コードを載せました。色塗り潰しなしの色付きエッジで表示します。図例では2つの重ね合わせですが、数が多い場合に分布の比較がし易くなります。
さらに、下図のように度数分布表をcsvファイルへ出力する仕様です。
■本プログラム
#!/usr/bin/env python # coding: utf-8 # In[1]: import os import pandas as pd import numpy as np import math import matplotlib.pyplot as plt from matplotlib.patches import Rectangle import japanize_matplotlib plt.rcParams['font.size'] = 18 # グラフの基本フォントサイズの設定 # データ1のcsvファイルを読み込む file_path_1 = 'data_dir/data1.csv' df_1 = pd.read_csv(file_path_1) data1_np = df_1['Value'].values min1 = min(data1_np) max1 = max(data1_np) data1_size = len(data1_np) print(min1, max1, data1_size) # In[2]: # データ2のcsvファイルを読み込む file_path_2 = 'data_dir/data2.csv' df_2 = pd.read_csv(file_path_2) data2_np = df_2['Value'].values min2 = min(data2_np) max2 = max(data2_np) data2_size = len(data2_np) print(min2, max2, data2_size) # In[3]: # 全データ区間の最小値と最大値を取得 if min1 <= min2: my_min = min1 # データ1の最小値を最小値とする else: my_min = min2 # データ2の最小値を最小値とする if max1 >= max2: my_max = max1 # データ1の最大値を最大値とする else: my_max = max2 # データ2の最大値を最大値とする print(my_min, my_max) # In[4]: # データ1と2で、データ数が大きい方をデータ数とする if data1_size >= data2_size: N = data1_size else: N = data2_size print(N) # In[5]: # スタージェスの公式より # 階級数を決める my_class_size = int(1 + math.log2(N)) print('my_class_size', my_class_size) # 階級幅(グラフ化には不要) my_class_width = (my_max - my_min) / my_class_size print('my_class_width', my_class_width) # In[6]: x_name = '寸法出来栄え' y_name = '個数' legend_name = 'データ' plt.hist(data1_np, bins = my_class_size, range = (my_min, my_max), histtype = 'step', edgecolor = 'r', linewidth = 2, label = os.path.basename(file_path_1)) plt.hist(data2_np, bins = my_class_size, range = (my_min, my_max), histtype = 'step', edgecolor = 'k', linewidth = 2, label = os.path.basename(file_path_2)) plt.xlabel(x_name) plt.ylabel(y_name) plt.legend(bbox_to_anchor = (1.00, 1), title = legend_name) plt.grid() #plt.xlim(0, 10) #plt.savefig('histogram.jpg') plt.show() # In[7]: # ヒストグラムの数値データを取得する関数 def extract_hist_data_func(DATA, CLASS_SIZE, MIN, MAX, FILE_NAME): # 階級幅 class_width = (MAX - MIN) / CLASS_SIZE # 階級 bins = np.arange(MIN, MAX + class_width, class_width) # 階級値 class_value = (bins[1:] + bins[:-1]) / 2 # 度数 hist = np.histogram(DATA, bins)[0] # 階級の範囲 class_name = [f'{bins[i]}以上{bins[i+1]}未満' for i in range(hist.size)] # 累積和 cumsum = hist.cumsum() # 相対度数 relative_hist = hist / cumsum[-1] # 累積相対度数 cumsum_relative_hist = cumsum / cumsum[-1] ### # 列データをリストで作成 column_data_list = list(zip( class_name, # 1. 階級の範囲 class_value, # 2. 階級値 hist, # 3. 度数 cumsum, # 4. 累積和 relative_hist, # 5. 相対度数 cumsum_relative_hist, # 6. 累積相対度数 )) # pandasデータフレームを作成 df_buf = pd.DataFrame(column_data_list, columns = ['階級', '階級値', '度数', '累積和', '相対度数', '累積相対度数']) # インデックスを1から振り直す df_buf.index = np.arange(1, len(df_buf) + 1) # csvファイルに出力 df_buf.to_csv(FILE_NAME + '.csv', encoding = 'utf_8_sig') # 作成したヒストグラムデータを抽出する関数を実行 extract_hist_data_func(data1_np, my_class_size, my_min, my_max, 'データ1') extract_hist_data_func(data2_np, my_class_size, my_min, my_max, 'データ2')
(参考)ヒストグラムを色線ではなくて、色塗りつぶしで表現したい場合は、下記を参考下さい。
以上
<広告>
リンク
リンク