光電效應及普朗克常數的測定數據處理 Python實現

內容僅供參考,如有錯誤,歡迎指正,如有疑問,歡迎交流。?

因為我不會Excel所以只能用Python來處理

祝大家早日擺脫物理實驗的苦海

用到的一些方法

PCHIP (分段三次埃爾米特插值多項式)

因為實驗時記錄的數據比較少,記錄的也比較隨便,直接將這些數據連起來的話畫出的圖像十分的直,而伏安特性曲線顧名思義應該是一條曲線,因此我們需要進行數據擬合,但是呢我們發現直接進行數據擬合會出現下面的情況,即在某些區間內,電壓上升電流反而下降了,這很不合理,所以我讓AI幫我想到了PCHIP插值法進行數據點的擴展,具體是啥我也不知道,反正用就完了

利用導數找拐點

看了示范報告,一開始把零點當成拐點算了,爆炸了

找拐點的方法我試了好多種,二階導等于零、一階導的極值、一階導作差、一階導和各種閾值比較等等,最后我用的是區間斜率與整體斜率的比較,也算是一階導和閾值比較的一種吧。

這些方法的核心思想都是在伏安特性曲線上找到電流變化陡峭的拐點,并將其對應的電壓作為截止電壓,關鍵是怎樣才算陡峭。本文用到的方法中,先計算電流隨電壓的平均變化率(即平均斜率),作為基準值 threshold =(I_max - I_min) / (U_max - U_min),隨后遍歷所有插值后的數據點,利用五點差分法計算其局部斜率,如果這個局部斜率是基準斜率的1.5倍,就將其認為是拐點,記錄并退出循環。但是因為找到了第一個就退出循環了并且“1.5倍”不一定是每組數據的最佳選擇,所以結果可能會出現較大誤差。

threshold = (max(y_dense) - min(y_dense)) / (x_max - x_min)  # 導數閾值for i in range(nums_data):if (y_dense[i + 5] - y_dense[i]) / (x_dense[i + 5] - x_dense[i]) > threshold * 1.5:cutoff_voltage = x_dense[i]break

代碼

import openpyxl
import matplotlib.pyplot as plt
import numpy as np
import os
from matplotlib.ticker import FormatStrFormatter
from scipy.interpolate import PchipInterpolator
from docx import Document
from docx.shared import Inches# 設置支持中文的字體和正常顯示負號
plt.rcParams['font.sans-serif'] = ['SimHei']  # 或者 ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False# ------------------------------------------控制臺--------------------------------------------------
N = 5  # 數據組數cutoff_voltages = [] # 截止電壓 (V)
calculate = 1 # 數據計算+圖片輸出
save_to_word = 0 # 將圖片保存到 Word 文檔output_dir = r"C:\Users\86138\Desktop\這是文件夾\這是文件夾里的文件夾" # 指定圖片保存目錄
excel_file = r"C:\Users\86138\Desktop\這是文件夾\這是xlsx.xlsx"  # Excel 文件路徑 (用于加載原始數據和儲存計算后的數據)
word_file = r"C:\Users\86138\Desktop\這是文件夾\這是docx.docx"  # Word 文件路徑(用于讀取圖片并保存)# --------------------------------------------------------------------------------------------------auto = 0 if cutoff_voltages else 1
os.makedirs(output_dir, exist_ok=True)  # 確保目標文件夾存在def Htlang():# 物理常數c = 3.0e8  # 光速,單位 m/s# 1. 加載 Excel 文件wb = openpyxl.load_workbook(excel_file)sheet = wb.active# 2. 確定數據組的行間隔(第一組從第 1 行開始,每組占 2 行)group_start_rows = [1 + i * 2 for i in range(N)]  # 生成 [1, 3, 5, 7, 9]# 3. 存儲所有數據以便后續繪圖wavelengths = []     # 波長 (nm)frequencies = []     # 頻率 (10^-14 Hz)# 4. 處理每一組數據for group_idx, start_row in enumerate(group_start_rows, start=1):# 讀取表格名稱、坐標軸標簽table_name = sheet.cell(row=start_row, column=1).value  # A列存儲波長信息(例如 "365nm")x_label = sheet.cell(row=start_row, column=2).value       # B列第一行: 橫坐標標簽(電壓)y_label = sheet.cell(row=start_row + 1, column=2).value     # B列第二行: 縱坐標標簽(電流)# **處理 y_label,將乘方變為上標**if y_label:y_label = y_label.replace("10-10", r"$10^{-10}$") \.replace("10-11", r"$10^{-11}$") \.replace("10-12", r"$10^{-12}$")# 讀取電壓與電流數據(從 C 到 L 列)voltage_data = []current_data = []for col in range(3, 13):  # C(3)到L(12)v = sheet.cell(row=start_row, column=col).value  # 電壓數據i = sheet.cell(row=start_row + 1, column=col).value  # 電流數據voltage_data.append(v)current_data.append(i)# 計算頻率# 從 table_name 中去除末尾兩個字符(例如 "nm")轉換為 int 得到波長wavelength_nm = int(table_name[:-2])wavelength_m = wavelength_nm * 1e-9  # 轉換為 mfrequency = c / wavelength_m  # 計算頻率 (Hz)frequency_14 = frequency / 1e14  # 以 10^-14 Hz 為單位wavelengths.append(wavelength_nm)frequencies.append(frequency_14)# 過濾并排序有效數據valid_indices = [i for i, (v, i_val) in enumerate(zip(voltage_data, current_data))if v is not None and i_val is not None]x = np.array([voltage_data[i] for i in valid_indices])y = np.array([current_data[i] for i in valid_indices])# 按電壓升序排列sort_idx = np.argsort(x)x_sorted = x[sort_idx]y_sorted = y[sort_idx]if auto:cutoff_voltage = Noneelse:cutoff_voltage = cutoff_voltages[group_idx - 1]try:# 使用保形插值(保證單調性)pchip = PchipInterpolator(x_sorted, y_sorted)nums_data = 300# 生成密集采樣點,用于繪制曲線(擴展范圍為原數據范圍兩側各擴展10%)x_min, x_max = np.min(x_sorted), np.max(x_sorted)x_range = x_max - x_minx_dense = np.linspace(x_min - 0.1*x_range, x_max + 0.1*x_range, nums_data)y_dense = pchip(x_dense)if auto:threshold = (max(y_dense) - min(y_dense)) / (x_max - x_min)  # 導數閾值for i in range(nums_data):if (y_dense[i + 5] - y_dense[i]) / (x_dense[i + 5] - x_dense[i]) > threshold * 1.5:cutoff_voltage = x_dense[i]breakexcept Exception as e:print(f"[{group_idx}] 插值失敗,使用線性連接: {str(e)}")cutoff_voltage = Nonex_dense = x_sortedy_dense = y_sortedif auto:if cutoff_voltage is not None:print(f"[{group_idx}] 拐點確定的截止電壓: {cutoff_voltage:.3f} V")else:print(f"[{group_idx}] 未檢測到拐點,截止電壓無法確定")cutoff_voltages.append(cutoff_voltage)# 繪制伏安特性曲線plt.figure(figsize=(10, 7))plt.plot(x_dense, y_dense, 'b-', linewidth=2, label="擬合曲線")plt.scatter(x_sorted, y_sorted, c='red', s=50, marker='o',edgecolors='k', label="實驗數據")if cutoff_voltage is not None:plt.axvline(cutoff_voltage, color='red', linestyle='--', label=f"截止電壓: {cutoff_voltage:.2f} V")plt.xlabel(x_label)plt.ylabel(y_label)plt.title(f"伏安特性曲線,波長 {table_name}")plt.grid(True)plt.legend()plt.tight_layout()output_path = os.path.join(output_dir, f"output_{group_idx}.png")plt.savefig(output_path, dpi=300)plt.close()print(f"[{group_idx}] 圖像已保存至: {output_path}")# 5. 線性擬合:截止電壓 vs 頻率(計算擬合參數及其不確定度)freq_array = np.array(frequencies)volt_array = np.array(cutoff_voltages, dtype=float)# 使用 cov=True 得到參數協方差矩陣coeffs, cov = np.polyfit(freq_array, volt_array, 1, cov=True)k, b = coeffserr_k = np.sqrt(cov[0, 0])  # 斜率 k 的標準差,即不確定度# 6. 繪制截止電壓 vs 頻率 圖(增加數據點連接線,并設置刻度格式)plt.figure(figsize=(8, 6))plt.scatter(freq_array, volt_array, color='blue', label="實驗數據")plt.plot(freq_array, volt_array, 'b-', label="數據連接線")plt.plot(freq_array, k * freq_array + b, 'r--', label=f"擬合直線: $U_s = {k:.4f}f + {b:.4f}$\n斜率不確定度: ±{err_k:.4f}")plt.xlabel(r"頻率 ($10^{-14}$ Hz)")plt.ylabel("截止電壓 (V)")plt.title("截止電壓-頻率圖線")plt.grid(True)plt.legend()ax = plt.gca()ax.xaxis.set_major_formatter(FormatStrFormatter('%.3f'))  # 橫軸保留三位小數ax.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))  # 縱軸保留兩位小數plt.tight_layout()output_path = os.path.join(output_dir, f"output_{N + 1}.png")plt.savefig(output_path, dpi=300)plt.close()print(f"截止電壓-頻率圖已保存至: {output_path}")# 7. 計算普朗克常數h0 = 6.64 * 10**(-34)  # 公認普朗克常數 (J·s)e = 1.6 * 10**(-19)  # 電子電荷量 (C)h = e * (-k) * 1e-14  # 計算出的普朗克常數 (J·s)_h = e * err_k * 1e-14  # 計算出的普朗克常數的不確定度 (J·s)Ep = (h - h0) * 100 / h0# 8. 寫入 Excel# 將標題寫入 A15, A16, A17sheet["A15"] = "波長 (nm)"sheet["A16"] = "頻率 (10^-14 Hz)"sheet["A17"] = "截止電壓 (V)"# 假設數據組數為 5,對應寫入 B 到 F 列for i, (w, f, u) in enumerate(zip(wavelengths, frequencies, cutoff_voltages)):col_letter = chr(ord('B') + i)  # B, C, D, E, Fsheet[f"{col_letter}15"] = f"{w:.0f}"sheet[f"{col_letter}16"] = f"{f:.2f}"sheet[f"{col_letter}17"] = f"{u:.2f}"# 將計算結果寫入 Excel(從 A19 開始)sheet["A19"] = "h"sheet["B19"] = f"{h * 10 ** 34:.2f} × 10^(-34) J·s"sheet["A20"] = "Δh"sheet["B20"] = f"{_h * 10 ** 34:.2f} × 10^(-34) J·s"sheet["A21"] = "h±Δh"sheet["B21"] = f"{h * 10 ** 34:.2f} ± {_h * 10 ** 34:.2f} × 10^(-34) J·s"sheet["A22"] = "Ep"sheet["B22"] = f"{Ep:.2f}%"wb.save(excel_file)print("計算結果已寫入 Excel")print(f"{Ep:.2f}%")if save_to_word:from docx import Documentfrom docx.shared import Inchesdef Htlanglanglang():doc = Document()# 創建表格(3 行 2 列),確保六張圖片能排在一頁上table = doc.add_table(rows=3, cols=2)table.autofit = True  # 自動調整列寬img_index = 0  # 計數器for i in range(1, N + 2):  # 遍歷所有圖片(包括截止電壓-頻率圖)image_path = os.path.join(output_dir, f"output_{i}.png")if os.path.exists(image_path):row = img_index // 2  # 計算行號col = img_index % 2   # 計算列號cell = table.cell(row, col)  # 獲取單元格paragraph = cell.paragraphs[0]run = paragraph.add_run()run.add_picture(image_path, width=Inches(3))  # 調整寬度,確保 3 張圖片一行img_index += 1doc.save(word_file)print(f"實驗結果已保存至 Word: {word_file}")if calculate:Htlang()
if save_to_word:Htlanglanglang()

?操作步驟

第0步 創建所需文件

在電腦某個位置新建一個文件夾,然后在新建的文件夾里新建一個.xlsx文件、一個.py文件、一個.docx文件以及一個文件夾,完成后大概長下面這樣

第1步 填入數據、粘貼代碼

打開excel文件,將原始數據輸入,格式如下

注意:A列的幾個單元格要合并一下不然會報錯(我懶的調了),電流的單位中的-11次方這些不需要在excel中就給它改為上標不然不知道會不會報錯(我懶的試了)

打開Python文件,將代碼粘貼進去,并在代碼中注釋了控制臺的部分對文件路徑進行修改

第2步 安裝必要的Python擴展庫

打開cmd,輸入以下代碼(二選一)

pip install scipy
pip install python-docx
pip install openpyxl
pip install matplotlib
pip install numpy
pip install openpyxl matplotlib numpy scipy python-docx

第3步 運行代碼

一切順利的話運行結果大致如下

?此外,打開excel,會發現多了一些數據

文件夾里也會多出6張圖片

第4步 發現問題并稍加調整

因為找拐點的方法比較粗略,所以可能會存在較大的誤差,導致算出來的百分差嚴重超標,所以我們需要進行手動調整,然后將五個截止電壓在代碼中事先輸入,如下圖

第5步 再次運行代碼

我們需要不斷的調整和嘗試,直到把百分差降到10%以下

注意:運行時記得把excel關掉否則會報錯

第6步 把圖片保存到word中

經過不斷的調整,將百分差控制在10以內之后,將代碼中的save_to_word這個變量設置為1(當然一開始就設置為1也不是不行,開始教學之前我忘記改了),再次運行代碼(此時可以將變量calculate設置為0,不過無所謂,數據量不大,運行也耗不了多長時間),會發現輸出多了一句話

然后就可以打開word,按自己的需求調整圖片的大小(代碼已經初步調好了),然后去打印店打印結果了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73345.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73345.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73345.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025最新3個wordpress好用的主題

紅色大氣的wordpress企業主題,適合服務行業的公司搭建企業官方網站使用。是一款專為中小企業和個人開發者設計的WordPress主題,旨在提供專業的網站構建解決方案。 通過此WordPress主題,用戶可以輕松創建和維護一個專業的企業網站&#xff0c…

OLLVM 增加 CC++ 字符串加密功能

版權歸作者所有&#xff0c;如有轉發&#xff0c;請注明文章出處&#xff1a;https://cyrus-studio.github.io/blog/ 前言 當我們如果沒有對字符串進行加密&#xff0c;使用 IDA 反匯編一下 so 可以看到 C 代碼中的字符串就直接暴露了。 字符串加密原理 sobf.c #include <…

桑福德·韋爾策劃美國捷運公司收購南美銀行案例分析

桑福德韋爾(Sanford I. Weill)在1981年策劃美國捷運公司(American Express)以5.5億美元收購南美貿易發展銀行所屬外國銀行機構的案例中,展現了其作為戰略家與執行者的雙重能力。這一交易的流程和韋爾的具體行為可從以下六個關鍵環節解析: 一、戰略定位與目標篩選 戰略目標…

人工智能與區塊鏈融合:開啟數字信任新時代

引言 在當今數字化飛速發展的時代&#xff0c;人工智能&#xff08;AI&#xff09;與區塊鏈技術正以前所未有的速度改變著我們的生活和工作方式。AI以其強大的數據處理和智能決策能力&#xff0c;為各行業帶來了效率的飛躍&#xff1b;而區塊鏈則以其去中心化、不可篡改的特性…

自動化逆向框架使用(Objection+Radare2)

1. 工具鏈架構與核心優勢 1.1 動靜結合逆向體系 graph LR A[動態分析] -->|Objection實時Hook| B[關鍵點定位] B --> C[行為數據捕獲] D[靜態分析] -->|Radare2深度解析| E[控制流重建] E --> F[漏洞模式識別] B --> F C --> F 組合優勢對比&…

流式ETL配置指南:從MySQL到Elasticsearch的實時數據同步

流式ETL配置指南&#xff1a;從MySQL到Elasticsearch的實時數據同步 場景介紹 假設您運營一個電商平臺&#xff0c;需要將MySQL數據庫中的訂單、用戶和產品信息實時同步到Elasticsearch&#xff0c;以支持實時搜索、分析和儀表盤展示。傳統的批處理ETL無法滿足實時性要求&…

Docker-Volume數據卷詳講

Docker數據卷-Volume 一&#xff1a;Volume是什么&#xff0c;用來做什么的 當刪除docker容器時&#xff0c;容器內部的文件就會跟隨容器所銷毀&#xff0c;在生產環境中我們需要將數據持久化保存&#xff0c;就催生了將容器內部的數據保存在宿主機的需求&#xff0c;volume …

單片機和微控制器知識匯總——《器件手冊--單片機、數字信號處理器和可編程邏輯器件》

目錄 四、單片機和微控制器 4.1 單片機(MCU/MPU/SOC) 一、定義 二、主要特點 三、工作原理 四、主要類型 五、應用領域 六、選型與設計注意事項 七、發展趨勢 4.2 數字信號處理器(DSP/DSC) ?編輯?編輯 一、定義 二、工作原理 三、結構特點 四、應用領域 五、選型與設計注…

macOS 安裝 Miniconda

macOS 安裝 Miniconda 1. Quickstart install instructions2. 執行3. shell 上初始化 conda4. 關閉 終端登錄用戶名前的 base參考 1. Quickstart install instructions mkdir -p ~/miniconda3 curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o…

高數下---8.1平面與直線

目錄 平面的確定 直線的確定 若要求某一直線或平面就根據要素來求。 例題 平面中的特殊情況 平面中的解題思路 直線的解題思路 平面的確定 兩要素 一 一點 二 傾斜角 即法向量 點法式 可化為一般式 Ax By Cz D 0; (A,B,C) 即法向量&#xff1b; 改變D 即…

CMS遷移中SEO優化整合步驟詳解

內容概要 在CMS遷移過程中&#xff0c;系統化的規劃與執行是保障SEO排名穩定性的核心。首先需明確遷移流程的關鍵階段&#xff0c;包括數據備份、URL適配、元數據同步及安全配置等環節。其中&#xff0c;數據備份不僅需覆蓋原始數據庫與靜態資源&#xff0c;還需驗證備份文件的…

存儲過程、存儲函數與觸發器詳解(MySQL 案例)

存儲過程、存儲函數與觸發器詳解&#xff08;MySQL 案例&#xff09; 一、存儲過程&#xff08;Stored Procedure&#xff09; 定義 存儲過程是預先編譯好并存儲在數據庫中的一段 SQL 代碼集合&#xff0c;可以接收參數、執行邏輯操作&#xff08;如條件判斷、循環&#xff09;…

Python:進程間的通信,進程的操作隊列

進程間的隊列&#xff1a; 隊列的基本操作&#xff1a; 入隊&#xff1a;將數據放到隊列尾部 出隊&#xff1a;從隊列的頭部取出一個元素 maxsize&#xff1a;隊列中能存放數據個數的上限(整數)&#xff0c;一旦達到上限插入會導致阻塞&#xff0c;直到隊列中的數據被消費掉 …

【C++初階】--- 類與對象(中)

1.類的默認成員函數 默認成員函數就是??沒有顯式實現&#xff0c;編譯器會?動?成的成員函數稱為默認成員函數。?個類&#xff0c;我們不寫的情況下編譯器會默認?成以下6個默認成員函數&#xff0c;我們主要需要掌握前4個&#xff0c;后兩個了解以下即可&#xff0c;默認…

python處理音頻相關的庫

1 音頻信號采集與播放 pyaudio import sys import pyaudio import wave import timeCHUNK 1024 FORMAT pyaudio.paInt16 CHANNELS 1#僅支持單聲道 RATE 16000 RECORD_SECONDS 3#更改錄音時長#錄音函數&#xff0c;生成wav文件 def record(file_name):try:os.close(file_…

[M模擬] lc2711. 對角線上不同值的數量差(對角線遍歷+前后綴分解)

文章目錄 1. 題目來源2. 題目解析 1. 題目來源 鏈接&#xff1a;2711. 對角線上不同值的數量差 前置題&#xff1a; [M模擬] lc3446. 按對角線進行矩陣排序(對角線遍歷公式推導模板題) 矩形的對角線遍歷的基礎題。 題單&#xff1a; 待補充 2. 題目解析 2025年03月25日…

設計一個基于機器學習的光伏發電功率預測模型,以Python和Scikit - learn庫為例

下面為你設計一個基于機器學習的光伏發電功率預測模型&#xff0c;以Python和Scikit - learn庫為例。此模型借助歷史氣象數據和光伏發電功率數據來預測未來的光伏發電功率。 模型設計思路 數據收集&#xff1a;收集歷史氣象數據&#xff08;像溫度、光照強度、濕度等&#xf…

洛谷 P1351 [NOIP 2014 提高組] 聯合權值(樹)

題目描述 無向連通圖 G 有 n 個點&#xff0c;n?1 條邊。點從 1 到 n 依次編號,編號為 i 的點的權值為 Wi?&#xff0c;每條邊的長度均為 1。圖上兩點 (u,v) 的距離定義為 u 點到 v 點的最短距離。對于圖 G 上的點對 (u,v)&#xff0c;若它們的距離為 2&#xff0c;則它們之間…

YoloV8訓練和平精英人物檢測模型

概述 和平精英人物檢測&#xff0c;可以識別游戲中所有人物角色&#xff0c;并通過繪制框將人物選中&#xff0c;訓練的模型僅僅具有識別功能&#xff0c;可以識別游戲中的視頻、圖片等文件&#xff0c;搭配Autox.js可以推理&#xff0c;實現實時繪制&#xff0c;但是對手機性…

智能汽車圖像及視頻處理方案,支持視頻實時拍攝特效能力

在智能汽車日新月異的今天&#xff0c;美攝科技作為智能汽車圖像及視頻處理領域的先行者&#xff0c;憑借其卓越的技術實力和前瞻性的設計理念&#xff0c;為全球智能汽車制造商帶來了一場視覺盛宴的革新。美攝科技推出智能汽車圖像及視頻處理方案&#xff0c;一個集高效性、智…