Chart mit logarithmischer Achse

Rund um die LCL und andere Komponenten
Antworten
Linkat
Lazarusforum e. V.
Beiträge: 561
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22.1; Lazarus 4.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

Chart mit logarithmischer Achse

Beitrag von Linkat »

Hallo,

ich möchte mit der Chart-Komponente Messwerte einmal im linearen und einmal im logarithmischen Maßstab (Basis 10) darstellen. Zum Üben habe ich ein einfaches Beispielprojekt LogChart (s. Anhang) erzeugt.

Neben der TAChart- wird noch die ChartAxisTransformations-Komponente benötigt.
So wie es aussieht (vorausgesetzt ich mache keine Denk- oder Bedienfehler) funktioniert der logarithmische Maßstab nur sinnvoll, wenn ich für ymin=0 und ymax=1 eingebe (s. Bild_1 linear, Bild_2 logarithmisch). Man erkennt, dass nun die Achsenwerte potenziert werden. Erhöht man ymax mit SpinEdit auf 3, so zeigt die y-Achse 1000 (10hoch3) und als Grid wird nur eine Dekade dargestellt (s. Bild_3).

Code: Alles auswählen

unit LogChartU;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Buttons,
  ExtCtrls, Spin, StdCtrls, TATransformations, TAGraph;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    Chart1: TChart;
    ChartAxisTransformations1: TChartAxisTransformations;
    ChartAxisTransformations1LogarithmAxisTransform1: TLogarithmAxisTransform;
    Label1: TLabel;
    RadioGroup1: TRadioGroup;
    SpinEdit1: TSpinEdit;
    procedure FormCreate(Sender: TObject);
    procedure RadioGroup1Click(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1; 
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  SpinEdit1.Value:=10;
  Chart1.Extent.UseYMin:=True;
  Chart1.Extent.UseYMax:=True;
  Chart1.Extent.UseXMin:=True;
  Chart1.Extent.UseXMax:=True;
  Chart1.Extent.YMin:=0;
  Chart1.Extent.YMax:=SpinEdit1.Value;
  Chart1.Extent.XMin:=0;
  Chart1.Extent.XMax:=10;
  Label1.Caption:='ymax';
end;
 
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  case RadioGroup1.ItemIndex of
    0:ChartAxisTransformations1LogarithmAxisTransform1.Enabled:=False;
    1:ChartAxisTransformations1LogarithmAxisTransform1.Enabled:=True;
  end;
end;
 
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
  Chart1.Extent.YMax:=SpinEdit1.Value;
end;
 
end.
Mache ich ein Denk- oder Bedienfehler, oder ist die Komponente buggy?

Gruß, Linkat

PS: Sorry für die 'vergilbten' Screenshots. Lazarus 9.30.4
Dateianhänge
Logchart.zip
gezipptes Projekt
(126.47 KiB) 73-mal heruntergeladen
Bild 1
Bild 1
pic_1.jpg (50.92 KiB) 1304 mal betrachtet
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

ErnstVolker
Beiträge: 354
Registriert: Di 17. Feb 2009, 10:44
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Chart mit logarithmischer Achse

Beitrag von ErnstVolker »

Hallo Linkat,

gehe mal auf das Chart und anschließend im Objektinspektor auf LeftAxis->Intervals->Options und verändere da mal "aipUseCount" usw. auf True.

Da änderte sich was. Ich habe mal eben ein wenig gespielt. Siehe Bild im Anhang. Hoffe es hilft Dir vielleicht.

Ich geh' jetzt in die Falle. Gute Nacht allerseits.

Gruß

Volker
Dateianhänge
Bild.jpg
Bild.jpg (18.95 KiB) 1290 mal betrachtet

wp_xyz
Beiträge: 5175
Registriert: Fr 8. Apr 2011, 09:01

Re: Chart mit logarithmischer Achse

Beitrag von wp_xyz »

TAChart ist etwas verwirrend wegen der drei beteiligten Koordinaten-Systeme, ich zitiere aus http://wiki.lazarus.freepascal.org/TACh ... umentation" onclick="window.open(this.href);return false;:
"- Axis coordinates (known in some other applications as object coordinates) -- this is the "raw" coordinate values obtained from the data. As the name implies, axis coordinates are interpreted in terms of specific axis -- the same coordinate value may have different meaning depending on the axis it is applied to.
- Graph coordinates (aka world coordinates) are converted from the axis coordinates using axis transformation, such as logarithmic scale. Graph coordinates are common for all objects in the chart.
- Image coordinates (aka screen coordinates) are converted from graph coordinates based on the chart viewport. This transformation is always linear and can be influenced by chart tools such as zooming and panning. "
Der Chart.Exent bewegt sich im Bereich der "Graph"-Koordinaten, d.h. die Werte sind nach der Koordinatentransformation zu betrachten. Du musst also von deinen Min und Max-Werten die Zehnerlogarithmen bilden. Etwa so:

Code: Alles auswählen

uses
  math;
 
procedure TForm1.FormCreate(Sender: TObject);
const
  ymin = 1;
  ymax = 1000;
begin
  SpinEdit1.Value:=ymax;                 
  Chart1.Extent.UseYMin:=True;
  Chart1.Extent.UseYMax:=True;
  Chart1.Extent.UseXMin:=True;
  Chart1.Extent.UseXMax:=True;
  Chart1.Extent.YMin:=log10(ymin); 
  Chart1.Extent.YMax:=log10(SpinEdit1.Value);
  Chart1.Extent.XMin:=0;
  Chart1.Extent.XMax:=10;
  Label1.Caption:='ymax';
end;   
 
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
  Chart1.Extent.YMax:=log10(SpinEdit1.Value);
end;
Trickreich ist die Erstellung "schöner" Achsenlabels: Gehe zu den Eigenschaften der betreffenden Achse und wähle bei den Intervals die Option aipGraphCoords an und setze die Tolerance auf etwa 3-5. Damit wird die Achse meistens mit Zehnerpotenzen beschriftet. Je nach Zoomstufe oder Größe des Charts können aber auch krumme Werte auftauchen. Ich nehmen dann für die Beschriftung eine eigene ListChartSource, die ich mit den Zehnerpotenzen vorbesetze:

Code: Alles auswählen

procedure PopulateLogSource;
var
  i: Integer;
  z: double;
begin
  for i:=-20 to 20 do begin
    z := IntPower(10, i);
    ListChartSource1.Add(z, z);
  end;
end;
Wenn du später Kurven einfügst, darfst du auch nicht vergessen, die Indices AxisIndexX und AxisIndexY der Series auf die der Achsen in der AxisList des Chart einzutragen, sonst wird die Koordinatentransformation nicht auf die Kurvenwerte angewendet.

Ich weiß nicht, ob diese Features insgesamt in der offiziellen Lazarus-Version schon enthalten sind. Wenn nicht, hole dir einen aktuellen Snapshot.
Zuletzt geändert von Lori am Do 26. Apr 2012, 16:55, insgesamt 1-mal geändert.
Grund: richtiger Highlighter

Linkat
Lazarusforum e. V.
Beiträge: 561
Registriert: So 10. Sep 2006, 23:24
OS, Lazarus, FPC: Linux Mint 22.1; Lazarus 4.0 FPC 3.2.2; RaspiOS
CPU-Target: AMD 64, ARM 64
Wohnort: nr Stuttgart

Re: Chart mit logarithmischer Achse

Beitrag von Linkat »

Hallo Volker und wp_xyz,
vielen Dank für die Hinweise. Tatsächlich fehlen die Eigenschaften LeftAxis.Intervals unter Lazarus 9.30.4.

Im aktuellen SVN sind die Eigenschaften vorhanden. Ich bin also einen Schritt weiter. Aber die Komponente steckt noch mit einigen Ungereimtheiten bzw. Fehlern in den Kinderschuhen. Trotzdem ist die Komponente ein hervorragendes und mächtiges Tool. Alle Hochachtung an die Entwickler.

Ich werde an den vielen Stellschrauben noch etwas herumdrehen und ausprobieren.

Gruß,
Linkat
Linux Mint 21.3; Lazarus 3.4 FPC 3.2.2; RaspiOS

wp_xyz
Beiträge: 5175
Registriert: Fr 8. Apr 2011, 09:01

Re: Chart mit logarithmischer Achse

Beitrag von wp_xyz »

Aber die Komponente steckt noch mit einigen Ungereimtheiten bzw. Fehlern in den Kinderschuhen.
Das sehe ich nicht so. Ich gebe aber zu, dass TAChart ziemlich komplex ist und sich vieles nicht auf den ersten Blick erschließt, aber als "ungereimt" würde ich das nicht bezeichnen. Wenn ich bei meinem ersten Kontakt mit einem mir unbekannten Programm nicht auf Anhieb die besten Ergebnisse produzieren kann, dann sage ich doch auch nicht, dass das Programm noch in den Kinderschuhen steckt, sondern versuche durch Üben meine Fähigkeiten zu verbessern. Lies die oben angegebene Dokumentation und studiere die vielen beigefügten Beispiele. Und wenn du einen Fehler findest - davon gibt es sicher noch einige -, dann poste das Problem im englischen Lazarus-Forum (http://www.lazarus.freepascal.org/index ... tion=forum" onclick="window.open(this.href);return false;) oder im Lazarus Bug Tracker (http://www.lazarus.freepascal.org/index ... tion=forum" onclick="window.open(this.href);return false;), der Autor der Komponente ist sehr rührig und findet meist schnell eine Lösung.

Antworten