基于物理实验的Mathematica数据处理实例

目前暂时只记录在近代物理实验中适合使用模块化处理方式的代码,假如以后有时间和机会的话可能会涉及其他的内容

近代物理实验部分收工,可能以后有空会加一个心电图批量绘图? — 吴迪 2018/10/26 14:37

前一段时间帮一个化学系的同学做了一点批量数据处理,争取在6月份之前整理一下放进来代替上面预告的批量绘图,不过本页的题目可能就需要更改一下了m(吴迪 2019/04/29 19:34

这段代码的目的是通过从示波器上记录的数据在Mathematica软件中进行双纵坐标绘图,其中左右两组纵坐标分别对应不同的曲线,并将得到的函数封装为一个模块。 从示波器中记录的数据格式如图所示

plotdata[tmin_, tmax_, u1min_, u1max_, u2min_, u2max_, data_, name_] :=  Module[{plot1, plot2},
plot1 =    ListPlot[data[[10 ;;, 1 ;; 2]], Joined -> True,     PlotRange -> {{tmin, tmax}, {u1min, u1max}},     Frame -> {True, True, False, False}, Axes -> False,     ImageSize -> Large, ImagePadding -> {{70, 70}, {50, 30}},     FrameLabel -> {Style["扫描时间t/index", 12, FontFamily -> "楷体"],       Style["扫场电压/mV", 12, FontFamily -> "楷体"], Null,       Style["信号电压/mV", 12, FontFamily -> "楷体"]}];
plot2 =    ListPlot[data[[10 ;;, 1 ;; 3 ;; 2]], Joined -> True,     PlotRange -> {{tmin, tmax}, {u2min, u2max}}, Axes -> False,   Frame -> {False, False, False, True}, ImageSize -> Large,     ImagePadding -> {{70, 70}, {50, 30}}, FrameTicks -> All,     FrameLabel -> {{Null,        Style["信号电压/mV", 12, FontFamily -> "楷体"]}, {Null, Null}}];
Labeled[Overlay[{plot1, plot2}],    Style[name, 14, FontFamily -> "Times New Roman"]]]

主要思路是绘出两张形状相同的图,之后利用Overlay函数将两张图组合起来。其中形状相同利用了ImagePadding函数,最后利用Labeled函数生成图像名称。

以上思路与代码实现参考了百度贴吧与stackexchange上的相关讨论

在自带帮助发现了如下howto|生成具有两个垂直坐标的图形 官方教程,不确定在11.3之前的版本是否具有该帮助页面
Mathematica内部链接为 howto/GeneratePlotsWithTwoVerticalScales ,在线链接为官网帮助链接,详解为待补天坑,欢迎大佬帮忙补全 — 2018/12/09

smooth[data_, datanew_] :=
Module[{u = {data[[1, 2]]}, length = Length[data]},
datanew = {{}};
Do[
 If[data[[n - 1, 1]] == data[[n, 1]],
  u = Join[u, {data[[n, 2]]}],
  datanew = Join[datanew, {{data[[n - 1, 1]], Mean[u]}}]; 
  u = {data[[n, 2]]}]
 , {n, 2, length}];
datanew = datanew[[2 ;;]];
]

使用时需要注意第二个变量必须是空的,未赋值的,原因可能是由于module内部变量重命名而无法覆盖掉原变量定义
该算法要求数据已排序好,可以使用Sort[]函数
需要说明的是,这里所说的“平滑化处理”是基于原数据在相同位置测量得到多组数据而将在同一位置测得的数据取平均得到的,效果如图所示

首先贴上长长的代码如下

checkTe[datae_, l1end_, l0begin_, l0end_, l2begin_] := Module[
{line0, line1, line2, s, slope, y, tempK, tempeV},

Print[ListPlot[datae]];
line1 = LinearModelFit[datae[[1 ;; l1end]], x, x];
   Print[Show[ListPlot[datae[[1 ;; l1end]]], Plot[line1[x], {x, -100, -30}]]];
   Print["AdjustedRSquared=", line1["AdjustedRSquared"]]; 
line0 = LinearModelFit[datae[[l0begin ;; l0end]], x, x];
   Print[Show[ListPlot[datae[[l0begin ;; l0end]]], Plot[line0[x], {x, -10, 10}]]];
   Print["AdjustedRSquared=", line0["AdjustedRSquared"]];
line2 = LinearModelFit[datae[[l2begin ;;]], x, x];
   Print[Show[ListPlot[datae[[l2begin ;;]]],Plot[line2[x], {x, 30, 100}]]];
   Print["AdjustedRSquared=", line2["AdjustedRSquared"]];
Print[line1["BestFitParameters"][[2]],line2["BestFitParameters"][[2]]];
   Print["S =", s = (line1["BestFitParameters"][[2]] + line2["BestFitParameters"][[2]])/2];
   Print["slope =", slope = line0["BestFitParameters"][[2]]];
   Print["y =", y = Abs[line1["BestFitParameters"][[1]]] + Abs[line2["BestFitParameters"][[1]]]];
   Print["temp = ",tempK = 1/4 1.6 10^-19/(1.38 10^-23)*y/(slope - 0.82 s), " K"];
   Print["temp = ", tempeV = 1/4*y/(slope - 0.82 s), " eV"];
Show[ListPlot[datae, PlotStyle -> Blue(*PlotMarkers\[Rule]{"\[CircleDot]",12}*)], 
   Plot[line0[x], {x, -10, 10}, PlotStyle -> Red], 
   Plot[line1[x], {x, -100, 10}, PlotStyle -> Red], 
   Plot[line2[x], {x, -10, 100}, PlotStyle -> Red],
   Epilog -> Inset[Grid[{{Style["T=", 18], Style[tempK "K", 18]}, {Null, Style[tempeV "eV", 18]}}], {60, -3}]]
]

为了方便阅读,上述代码中每一小段代码的开头是左对齐的,小段内部的代码距最左侧相隔3个字符

我们首先来介绍一下模块(Module[])函数的用法。Module[{x,y,…},expr]是自带帮助中的第一个代码用法,其中{x,y,…} 声明模块内部使用的局部变量,后面的expr是被模块具体封装的部分。对于上面的代码,我们首先定义一个函数checkTe[datae_, l1end_, l0begin_, l0end_, l2begin_],该函数有5个参量,之后使用延迟赋值(:= )将该函数定义为一个具体的封装好的模块。

对于模块内部的几个部分,首先是

Print[ListPlot[datae]];

容易理解这将数据点先完整的展示出来。接着是

line1=...
line0=...
line2=...

这三部分分别将三段近似线性的数据点进行线性拟合

 Print[line1=...

这一部分利用理论的计算方法将电子温度计算出来并输出,其中输出line1[“BestFitParameters”][ [2] ],line2[“BestFitParameters”][ [2] ]是为了比较两段斜率是否相近,假如不相近可能是数据处理或实验本身存在问题。

理论公式可参看个人主页15307110078_吴迪_等离子体系列实验.pdf的第15页,该数据处理的背景也基于此。 最后利用

  Show[...

将得到的完整图像与测量出的温度展示出来

一个典型的输出结果如下图所示

如预告所示,这里展示对于一组格式类似的数据的批量处理方法。将整理好的数据文件放在一个文件夹中,并在此文件夹中新建一个Mathematica文档,首先输入如下代码:

SetDirectory[NotebookDirectory[]]

这一行代码的目的是将当前文件夹设为Mathematica的工作文件夹,之后关于文件的操作都限定在该文件夹中进行。这里作为例子,给出需要处理的数据example1

 好像是上次编辑的没保存上去...如果时间充裕的话可能在7月内能补上--- //[[153071100078@fudan.edu.cn|吴迪]] 2020/06/18 21:41//
欢迎留言与建议 — 吴迪 2018/06/10 12:19
吴迪,太赞了! — 乐永康 2018/10/01 21:35
乐老师来监工…看来剩下的部分要尽快整理出来了 — 吴迪 2018/10/14 14:24
  • home/students/15307110078/mmainexpr.txt
  • 最后更改: 2020/06/18 21:42
  • 由 hermione_evans