#作者:王日睿
#中国科学技术大学生命科学学院
#2021.12.30
#物理化学实验:实验09 溶液中的吸附作用和表面张力的测定
# Jupyter lab
import pandas as pd
import os
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 数据转utf-8
from chardet.universaldetector import UniversalDetector
def get_filelist(path):
Filelist = []
for home, dirs, files in os.walk(path):
for filename in files:
# 文件名列表,包含完整路径
if ".txt" in filename:
Filelist.append(os.path.join(home, filename))
# # 文件名列表,只包含文件名
# Filelist.append( filename)
return Filelist
def get_encode_info(file):
with open(file, 'rb') as f:
detector = UniversalDetector()
for line in f.readlines():
detector.feed(line)
if detector.done:
break
detector.close()
return detector.result['encoding']
def read_file(file):
with open(file, 'rb') as f:
return f.read()
def write_file(content, file):
with open(file, 'wb') as f:
f.write(content)
def convert_encode2utf8(file, original_encode, des_encode):
file_content = read_file(file)
file_decode = file_content.decode(original_encode,'ignore')
file_encode = file_decode.encode(des_encode)
write_file(file_encode, file)
filePath = './wangrirui/wangrirui'
Filelist = get_filelist(filePath)
for filename in Filelist:
file_content = read_file(filename)
encode_info = get_encode_info(filename)
if encode_info != 'utf-8':
convert_encode2utf8(filename, encode_info, 'utf-8')
encode_info = get_encode_info(filename)
# 除去那些不要的文件
file = os.listdir('./wangrirui/wangrirui')
file.pop(0)
file.pop(5)
def readfile(filename):
x, y = [], []
file = open(filename, 'r')
count = 0
for line in file.readlines():
count = count + 1
if count >= 2:
x.append(float(line[0:6]))
y.append(float(line[7:len(line)]))
return x, y
time, data = [], []
for i in range(len(file)):
t, d = readfile('./wangrirui/wangrirui/'+file[i])
time.append(t)
data.append(d)
# 绘制原始图片
color = ["black", "brown", "purple", "blue", "green", "crimson", "peru", "navy"]
label = ["纯水","加入0.4ml正丁醇","加入0.8ml正丁醇","加入1.2ml正丁醇","加入1.6ml正丁醇","加入2.0ml正丁醇","加入2.4ml正丁醇","加入2.8ml正丁醇"]
fig, ax = plt.subplots(4, 2, figsize=(7,10), dpi=400)
count = 0
for i in range(4):
for j in range(2):
ax[i][j].plot(time[count], data[count], color=color[count], label=label[count])
ax[i][j].grid(True)
ax[i][j].set_xlabel("时间/s")
ax[i][j].set_ylabel("压力差/Pa")
ax[i][j].legend()
count += 1
ax[1][0].set_ylim([265,293])
ax[2][0].set_ylim([230,260])
ax[3][0].set_ylim([210.5,227])
ax[3][1].set_ylim([197.5,210])
plt.tight_layout()
plt.savefig("raw_data.png")
# 求密度
V = np.arange(0,3.2,0.4)
rho = 0.81
M = 74.12
V_vol = 0.1
C = [round(rho*V[i]/M/V_vol,4) for i in range(len(V))]
print("浓度为:", C)
>浓度为: [0.0, 0.0437, 0.0874, 0.1311, 0.1749, 0.2186, 0.2623, 0.306]
from collections import Counter
counter = []
for i in range(len(data)):
counter.append(Counter(sorted(data[i])))
# 找到counter里面的大值(同时出现很多次)
P_max = [381, 329, 290, 272, 256, 238, 224, 209]
# 毛细管系数
K = 71.95/381
print(K)
>0.18884514435695537
sigma = [round(K*P_max[i],1) for i in range(8)]
print(sigma)
>[72.0, 62.1, 54.8, 51.4, 48.3, 44.9, 42.3, 39.5]
from scipy.optimize import curve_fit
def func(x, a, k, b):
return a*np.log(1+k*x)+b
a, k, b = curve_fit(func, C, sigma, bounds=([-100,-100,-100],[100,100,100]))[0]
print(a,k,b)
>-16.66501615166447 18.92593134925644 71.96283816006482
def get_R_square(x, y, a, k, b):
y_mean = np.mean(y)
y_predict = [a*np.log(1+k*e)+b for e in x]
TSS = [(x-y_mean)**2 for x in y]
RSS = [(y_predict[i] - y[i])**2 for i in range(len(y))]
return 1 - sum(RSS) / sum(TSS)
R_2 = get_R_square(C, sigma, a, k, b)
print(R_2)
>0.9979396073597314
plt.figure(dpi=400)
X = np.arange(-0.02, 0.32, 0.01)
plt.plot(X, func(X, a, k, b),label="拟合曲线")
plt.scatter(C, sigma, color="red",label="原始数据点")
plt.grid(True)
plt.text(0.11,72,s="拟合曲线为y=%.3fln(1+%.3fx)+%.3f"%(a,k,b),fontsize=10)
plt.text(0.26,69,s="$R^2$=%.4f"%R_2,fontsize=10)
plt.legend()
plt.xlabel("浓度C/M")
plt.ylabel("$sigma$ mN/m")
plt.savefig("fit1.png")
# 拟合方程的导数
def partial(c):
return -315.40/(1+18.326*c)
#吸附量
Gamma = [(-C[i]*partial(C[i])/8.314/(273.15+25))*1e-3 for i in range(len(C))]
print(Gamma)
>[0.0, 3.0876045220767628e-06, 4.274372228388533e-06, 4.902487399277195e-06, 5.2919802156622e-06, 5.55610762796605e-06, 5.747382028342844e-06, 5.8922923145789125e-06]
# 最后拟合得到Gamma_infty
# 舍去第一个0/0的点
Y_fit = [C[i]/Gamma[i] for i in range(1,len(C))]
X_fit = C[1:]
def linear_fit(x,k,b):
return k*x+b
k_lfit, b_lfit = curve_fit(linear_fit, X_fit, Y_fit)[0]
print(k,b)
>144029.29241154093 7859.28693722257
def get_R_square_2(x, y, k, b):
y_mean = np.mean(y)
y_predict = [k*e+b for e in x]
TSS = [(x-y_mean)**2 for x in y]
RSS = [(y_predict[i] - y[i])**2 for i in range(len(y))]
return 1 - sum(RSS) / sum(TSS)
R_2_l = get_R_square_2(X_fit, Y_fit, k_lfit, b_lfit)
print(R_2_l)
>1.0
plt.figure(dpi=400)
X = np.arange(0.04, 0.32, 0.001)
plt.plot(X, linear_fit(X,k_lfit,b_lfit),label="拟合曲线")
plt.scatter(X_fit, Y_fit, color="red",label="拟合数据点")
plt.grid(True)
plt.text(0.03,4.5e4,s=r"拟合曲线为$frac{c}{Gamma}$=%.3fc+%.3f"%(k_lfit,b_lfit),fontsize=10)
plt.text(0.03,4.2e4,s="$R^2$=%.4f"%R_2_l,fontsize=10)
plt.legend()
plt.xlabel("浓度C/M")
plt.ylabel(r"$frac{c}{Gamma}$",fontsize=15,rotation=0)
plt.ticklabel_format(style='sci',scilimits=(0,0),axis='y')
plt.savefig("fit2.png")
g_in = 1/k_lfit
S0 = 1/6.02214076e23/g_in
# 绘制Langmuir等温方程式
K = 1/(7859.287*g_in)
print(K)
def Langmuir(c):
return g_in*K*c/(1+K*c)
X_Lang = np.linspace(0,0.5)
Y = Langmuir(X_Lang)
plt.figure(dpi=400)
plt.plot(X_Lang,Y,label="Langmuir等温曲线")
plt.scatter(C,Gamma, color="red",label="数据点")
plt.grid(True)
plt.legend()
plt.xlabel("浓度C/M")
plt.ylabel(r"$Gamma~~ mol/m^2$",fontsize=10)
plt.ticklabel_format(style='sci',scilimits=(0,0),axis='y')
plt.savefig("langmuir.png")