Delphi 如何使用TeeChart生成此类图表?

Delphi 如何使用TeeChart生成此类图表?,delphi,teechart,Delphi,Teechart,使用粘贴在末尾的数据点,我得到了一张使用TeeChart的图表,如下图所示(第二幅图)。然而,我想要得到的是第一张图片(黑线)。我想知道怎么做?任何意见(关于如何做或关于算法)都将不胜感激 GaussView(红外光谱) 通过TeeChart 数据 引用您的数据源: 1801.43 124.4060 2501.45 2817.4313 及 及 TeeChart正在正确呈现给定数据。 . 如果要更改数据和图形,则应添加丢失的数据点 您需要决定增加计数的频率(超过哪些X步)。从y-

使用粘贴在末尾的数据点,我得到了一张使用TeeChart的图表,如下图所示(第二幅图)。然而,我想要得到的是第一张图片(黑线)。我想知道怎么做?任何意见(关于如何做或关于算法)都将不胜感激

GaussView(红外光谱)

通过TeeChart

数据
引用您的数据源:

 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.