Delphi 如何使用TeeChart生成此类图表?
使用粘贴在末尾的数据点,我得到了一张使用TeeChart的图表,如下图所示(第二幅图)。然而,我想要得到的是第一张图片(黑线)。我想知道怎么做?任何意见(关于如何做或关于算法)都将不胜感激 GaussView(红外光谱) 通过TeeChart 数据Delphi 如何使用TeeChart生成此类图表?,delphi,teechart,Delphi,Teechart,使用粘贴在末尾的数据点,我得到了一张使用TeeChart的图表,如下图所示(第二幅图)。然而,我想要得到的是第一张图片(黑线)。我想知道怎么做?任何意见(关于如何做或关于算法)都将不胜感激 GaussView(红外光谱) 通过TeeChart 数据 引用您的数据源: 1801.43 124.4060 2501.45 2817.4313 及 及 TeeChart正在正确呈现给定数据。 . 如果要更改数据和图形,则应添加丢失的数据点 您需要决定增加计数的频率(超过哪些X步)。从y-
引用您的数据源:
1801.43 124.4060
2501.45 2817.4313
及
及
TeeChart正在正确呈现给定数据。
.如果要更改数据和图形,则应添加丢失的数据点 您需要决定增加计数的频率(超过哪些X步)。从y-zero的哪个增量将意味着取消传播(因为在你的眼睛中,差异变得微不足道) 然后你要做一个多项式公式,确定每个峰值周围的值相对于峰值的绝对值下降的速度。类似于
y==y0/(a*(x-x0)^4+b*(x-x0)^2+c)
或类似的东西。你应该试试这个和那个,最后得到适合你口味的系数和幂的数量
然后围绕每个峰值(也称为主要源数据点),您应该添加这些次要的计算点,直到它们非常接近y-zero,或者直到它们满足来自相邻数据点的次要值(首先发生)
根据y0
、y1
和abs(x0-x1)
的不同,您可以推导出一个公式,其中两个传播波将相互作用,或者您可以懒惰地从两个方向计算完整路径,然后只插入最大y值
这个次要的,增强的系列赛,你可以通过茶几,它会显示你喜欢什么
顺便说一句,看看mitov.com——他几乎没有免费的组件,但也许会有合适的
PPS。用于丰富数据的非常粗略的草稿
估算功能和配置应手动调整,以获得最佳结果,无论“最佳”的含义是什么。正如TLama非常友好地建议的,解决方案单独发布: [解决方案] 曲线图之间的差异是由于洛伦兹线展宽造成的。看见非常感谢您的评论!下面给出了一个非常基本的工作示例:
unit uCurvFit;
interface
uses
uRtlTypes,
Math, SysUtils;
type
TLineShapeFitFunc = (lsffLorentz, lsffGauss);
TLineShapeFit = function(const RelOffset: Double): Double;
function Lorentz(const RelOffset: Double): Double;
function Gauss(const RelOffset: Double): Double;
procedure SpectrumFit(const OriginalFrequencies, OriginalIntensities
: TADouble; LineShapeFitFunc: TLineShapeFitFunc; var NFreqs: Integer;
var NewFrequencies: TADouble; var NewIntensities: TADouble);
implementation
function Lorentz(const RelOffset: Double): Double;
begin
Result := 1.0 / (1.0 + RelOffset * RelOffset);
end;
function Gauss(const RelOffset: Double): Double;
const
nln2: Double = -0.301029996; // - Log10(2.0);
begin
Result := Exp(nln2 * RelOffset * RelOffset);
end;
procedure SpectrumFit(const OriginalFrequencies, OriginalIntensities
: TADouble; LineShapeFitFunc: TLineShapeFitFunc; var NFreqs: Integer;
var NewFrequencies: TADouble; var NewIntensities: TADouble);
const
FrequencyStep: Double = 1.0;
HwHm: Double = 20.0; // Full Width at Half Maximum
var
I, J: Integer;
MaxFreq, MinFreq: Double;
Intensity, Freq, Center, RelOffset: Double;
LineShapeFit: TLineShapeFit;
begin
MaxFreq := 4000;
MinFreq := 0;
for I := 0 to Length(OriginalFrequencies) do
begin
if MaxFreq < OriginalFrequencies[I] then
MaxFreq := OriginalFrequencies[I];
if MinFreq > OriginalFrequencies[I] then
MinFreq := OriginalFrequencies[I];
end;
case LineShapeFitFunc of
lsffLorentz:
LineShapeFit := Lorentz;
lsffGauss:
LineShapeFit := Gauss;
end;
NFreqs := 1 + Trunc((MaxFreq - MinFreq) / FrequencyStep);
SetLength(NewFrequencies, NFreqs);
SetLength(NewIntensities, NFreqs);
for I := 0 to NFreqs - 1 do
begin
Intensity := 0.0;
Freq := MinFreq + I * FrequencyStep;
for J := 0 to Length(OriginalFrequencies) - 1 do
begin
Center := OriginalFrequencies[J];
RelOffset := (Freq - Center) / HwHm;
Intensity := Intensity + OriginalIntensities[J] * LineShapeFit(RelOffset);
end;
NewFrequencies[I] := Freq;
NewIntensities[I] := Intensity;
end;
end;
end.
单位uCurvFit;
接口
使用
URTLTYPE,
数学、系统;
类型
TLineShapeFitFunc=(lsffLorentz,lsffGauss);
TLineShapeFit=函数(const RelOffset:Double):Double;
函数洛伦兹(常数:双):双;
函数Gauss(const RelOffset:Double):Double;
程序频谱拟合(恒定原始频率、原始强度
:t双;LineShapeFitFunc:TLineShapeFitFunc;变量NFreqs:Integer;
var新频率:TADouble;var新强度:TADouble);
实施
函数洛伦兹(常数:双):双;
开始
结果:=1.0/(1.0+RelOffset*RelOffset);
结束;
函数Gauss(const RelOffset:Double):Double;
常数
nln2:Double=-0.301029996;//-Log10(2.0);
开始
结果:=Exp(nln2*RelOffset*RelOffset);
结束;
程序频谱拟合(恒定原始频率、原始强度
:t双;LineShapeFitFunc:TLineShapeFitFunc;变量NFreqs:Integer;
var新频率:TADouble;var新强度:TADouble);
常数
频率cystep:Double=1.0;
HwHm:Double=20.0;//半最大宽度
变量
一、 J:整数;
MaxFreq、MinFreq:双精度;
强度、频率、中心、重新偏移:双精度;
LineShapeFit:TLineShapeFit;
开始
最大频率:=4000;
MinFreq:=0;
对于I:=0到长度(原始频率)do
开始
如果MaxFreq<原始频率[I],则
MaxFreq:=原始频率[I];
如果MinFreq>原始频率[I],则
MinFreq:=原始频率[I];
结束;
的案例LineShapeFitFunc
lsffLorentz:
LineShapeFit:=洛伦兹;
高斯:
LineShapeFit:=高斯;
结束;
NFreqs:=1+Trunc((MaxFreq-MinFreq)/FrequencyScep);
设置长度(新频率、NFREQ);
设定长度(新强度、NFREQ);
对于I:=0至NFREQ-1 do
开始
强度:=0.0;
Freq:=MinFreq+I*FrequencyStep;
对于J:=0到长度(原始频率)-1 do
开始
中心:=原始频率[J];
RelOffset:=(频率-中心)/HwHm;
强度:=强度+原始强度[J]*线形系数(RelOffset);
结束;
新频率[I]:=Freq;
新强度[I]:=强度;
结束;
结束;
结束。
谢谢您的评论!我从来没有说过TeeChart的图像是错误的。GaussView图像似乎使用了某种峰值扩展算法,其中TeeChart图像的数据点直接相连。因此,我想知道TeeChart是否存在这样的算法。你所描述的是我自己提供额外的分数,同时对我来说太笼统了。好吧,如果你不想做你的算法,那就买别人的吧。看看米托夫的图书馆,也许你会在他的其中一套中找到你需要的东西。看看Torry.net,看看那些比较老的,大多是废弃的libs。我没有和TeeChart合作过。我没有看到你的资料来源和数据结构。所以我不能代替你写你的程序。我只能告诉你一般的方法。如果您不想购买第三方库,那么就开始编写peak expansions algo。当你遇到困难时,问一些关于这些困难的问题,问你的算法如何以及为什么不能工作。你提到的米托夫图书馆不适合这种情况,从他们的网站上建议说()我就是这么说的:(1)谢谢你的努力(2)你的话对我来说太笼统了。时期PS1:我从来没有说过我不想购买第三方库。我刚才说的是你提到的米托夫图书馆不适合这里。PS2:谢谢你启发我如何提出聪明的问题。看起来你的数据是某些波数下的线强度。为了将这些表示为光谱,可能需要更多的数据。通常每一行可以是r
2501.45 2817.4313
2892.60 1433.0563
2892.60 1433.0563
3010.32 37.5543
unit uCurvFit;
interface
uses
uRtlTypes,
Math, SysUtils;
type
TLineShapeFitFunc = (lsffLorentz, lsffGauss);
TLineShapeFit = function(const RelOffset: Double): Double;
function Lorentz(const RelOffset: Double): Double;
function Gauss(const RelOffset: Double): Double;
procedure SpectrumFit(const OriginalFrequencies, OriginalIntensities
: TADouble; LineShapeFitFunc: TLineShapeFitFunc; var NFreqs: Integer;
var NewFrequencies: TADouble; var NewIntensities: TADouble);
implementation
function Lorentz(const RelOffset: Double): Double;
begin
Result := 1.0 / (1.0 + RelOffset * RelOffset);
end;
function Gauss(const RelOffset: Double): Double;
const
nln2: Double = -0.301029996; // - Log10(2.0);
begin
Result := Exp(nln2 * RelOffset * RelOffset);
end;
procedure SpectrumFit(const OriginalFrequencies, OriginalIntensities
: TADouble; LineShapeFitFunc: TLineShapeFitFunc; var NFreqs: Integer;
var NewFrequencies: TADouble; var NewIntensities: TADouble);
const
FrequencyStep: Double = 1.0;
HwHm: Double = 20.0; // Full Width at Half Maximum
var
I, J: Integer;
MaxFreq, MinFreq: Double;
Intensity, Freq, Center, RelOffset: Double;
LineShapeFit: TLineShapeFit;
begin
MaxFreq := 4000;
MinFreq := 0;
for I := 0 to Length(OriginalFrequencies) do
begin
if MaxFreq < OriginalFrequencies[I] then
MaxFreq := OriginalFrequencies[I];
if MinFreq > OriginalFrequencies[I] then
MinFreq := OriginalFrequencies[I];
end;
case LineShapeFitFunc of
lsffLorentz:
LineShapeFit := Lorentz;
lsffGauss:
LineShapeFit := Gauss;
end;
NFreqs := 1 + Trunc((MaxFreq - MinFreq) / FrequencyStep);
SetLength(NewFrequencies, NFreqs);
SetLength(NewIntensities, NFreqs);
for I := 0 to NFreqs - 1 do
begin
Intensity := 0.0;
Freq := MinFreq + I * FrequencyStep;
for J := 0 to Length(OriginalFrequencies) - 1 do
begin
Center := OriginalFrequencies[J];
RelOffset := (Freq - Center) / HwHm;
Intensity := Intensity + OriginalIntensities[J] * LineShapeFit(RelOffset);
end;
NewFrequencies[I] := Freq;
NewIntensities[I] := Intensity;
end;
end;
end.