簡體   English   中英

如何從 30 個 csv 文件制作直方圖以繪制直方圖,然后使用高斯函數和標准差繪制直方圖?

[英]How to make a histogram from 30 csv files to plot the historgram and then for it with gaussian function and the standard deviation?

我想從 30 個 csv 文件制作直方圖,然后擬合高斯函數以查看我的數據是否最佳。 之后,我需要找到這些峰值的平均值和標准偏差。 文件數據太大,我不知道我是否提取了單個列並將它們的值范圍正確地組織到 bin 數中。

我知道這有點長,問題太多,請盡可能多地回答,非常感謝!

> 這是數據的鏈接

下面到目前為止我已經完成了(實際上並不多,因為我是數據可視化的初學者。)首先,我導入包, savgol_filter使 bin 透明,似乎更好。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.signal import savgol_filter

然后我轉換尺寸並設置限制。

def cm2inch(value):
    return value/2.54

width = 9
height = 6.75

sliceMin, sliceMax = 300, 1002

接下來,我通過迭代 30 次加載所有數據 jupyter notebook,在那里我設置了兩個數組“時間”和“電壓”來存儲值。

times, voltages = [], []
for i in range(30):
    time, ch1 = np.loadtxt(f"{i+1}.txt", delimiter=',', skiprows=5,unpack=True)
    times.append(time)
    voltages.append(ch1)    
t = (np.array(times[0]) * 1e5)[sliceMin:sliceMax]
voltages = (np.array(voltages))[:, sliceMin:sliceMax]

1. 我想我應該需要一個 hist 函數來繪制圖形。 雖然我有圖,但我不確定它是否是生成直方圖的正確方法。

hist, bin_edges = np.histogram(voltages, bins=500, density=True)
hist = savgol_filter(hist, 51, 3)
bin_centres = (bin_edges[:-1] + bin_edges[1:])/2

到目前為止,我已經達到了。 第三個峰值的幅度太低,這不是我所期望的。 但如果我的期望是錯誤的,請糾正我。

這是我的直方圖

我用以下代碼更新了我的情節

labels = "hist"
if showGraph:
    plt.title("Datapoints Distribution over Voltage [mV]", )      
    plt.xlabel("Voltage [mV]")
    plt.ylabel("Data Points")
    plt.plot(hist, label=labels)
    plt.show()

2.(編輯)我不知道為什么我的標簽不能顯示,你能糾正我嗎?

3.(編輯)此外,我想通過對直方圖使用高斯函數來制作擬合曲線。 但是有三個峰值,那么我應該如何將函數擬合到它們呢?

def gauss(x, *p):
A, mu, sigma = p
        return A*np.exp(-(x-mu)**2/(2.*sigma**2))

4.(編輯)我意識到我還沒有提到平均值。 我想如果我能找到峰值的最大值,那么我就可以找到特定峰值的平均值。 我需要先擬合高斯才能找到峰值,還是可以找到直線? 是否要找到局部最大值以便我可以找到它? 如果是,我該如何進行?

5.(已編輯)我知道如何從單個列表中找到標准偏差,如果我想做類似的邏輯,如何實現代碼?

sample = [1,2,3,4,5,5,5,5,10]
standard_deviation = np.std(sample, ddof=1)
print(standard_deviation)
  1. 要繪制直方圖,最普通的matplotlib函數hist是我的hist 基本上,如果我有一個samples列表,那么我可以通過以下方式用100 bin 繪制它們的直方圖:
import matplotlib.pyplot as plt
plt.hist(samples, bins=100)
plt.show()
  1. 如果您想將正態分布擬合到您的數據中,最好的模型是Gaussian Mixture Model ,您可以通過scikit-learn 的 GMM 頁面找到更多信息。 也就是說,這是我用來將奇異高斯分布擬合到數據集的代碼。 如果我想擬合k正態分布,我需要使用n_components=k 我還包括了結果圖:
from sklearn.mixture import GaussianMixture
import numpy as np
import matplotlib.pyplot as plt

data = np.random.uniform(-1,1, size=(800,1))
data += np.random.uniform(-1,1, size=(800,1))
gmm = GaussianMixture(n_components=1)
gmm.fit(data)
print(gmm.means_, gmm.covariances_)
mu = gmm.means_[0][0]
variance = gmm.covariances_[0][0][0]
print(mu, variance)
fig, ax = plt.subplots(figsize=(6,6))
Xs = np.arange(min(data), max(data), 0.05)
ys = 1.0/np.sqrt(2*np.pi*variance) * np.exp(-0.5/variance * (Xs + mu)**2)
ax.hist(data, bins=100, label='data')
px = ax.twinx()
px.plot(Xs, ys, c='r', linestyle='dotted', label='fit')
ax.legend()
px.legend(loc='upper left')
plt.show()

繪圖結果

至於問題 3,我不確定您想捕獲哪個軸的標准偏差。 如果你想得到列的標准偏差,你可以使用np.std(data, axis=1) ,並使用axis=0逐行標准偏差。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM