Achsen von QwtPlot

Dein Thema passt einfach in kein Forum? Dann probiers mal hier.
Antworten
Gora
Beiträge: 10
Registriert: 24. Mai 2013 16:16

Achsen von QwtPlot

Beitrag von Gora » 1. Juli 2013 17:04

Hallo Leute,

ich habe gerade ein Problem mit den Achsen von QWTPlot.

Wie das Bild aus dem Anhang zeigt möchte ich zwei QWTPlots mit zwei Achsen erstellen. Die beiden Achsen müssen so skaliert sein, dass der Nullpunkt der beiden Achsen zusammenfällt. Dazu ein Minimal-Beispiel:

Code: Alles auswählen

#include "qwt_plot.h"
#include <QVBoxLayout>
#include <QApplication>
#include "qwt_scale_draw.h"
#include "qwt_interval.h"
#include "qwt_scale_div.h"
#include "qwt_scale_engine.h"
#include "qwt_scale_map.h"
#include "qwt_scale_widget.h"
#include "qwt_plot_layout.h"
#include "qwt_plot_rescaler.h"


void redrawLayout(QwtPlot *, QwtPlot *, QVBoxLayout * );
void  createMainPlot();

int main(int argc, char **argv)
{
    QApplication a(argc, argv);
    createMainPlot();
    return a.exec();
}

void createMainPlot(){
    QwtPlot * plot1=new QwtPlot;
    QwtPlot * plot2=new QwtPlot;
    QVBoxLayout * layout=new QVBoxLayout;
    layout->addWidget(plot1);
    layout->setMargin(0);
    plot2->setLayout(layout);
    plot1->canvas()->setPalette(Qt::red);
    plot2->canvas()->setPalette(Qt::blue);
    plot1->setCanvasBackground( Qt::white );
    plot2->setCanvasBackground( Qt::white );
    plot1->setAxisScale(QwtPlot::xBottom,0,0.03,0.002);
    plot2->setAxisScale(QwtPlot::xBottom,0,0.03,0.002);
    plot1->setAxisTitle(QwtPlot::yLeft,"y1");
    plot2->setAxisTitle(QwtPlot::yLeft,"y2");
    plot1->setAxisScale(QwtPlot::yLeft,-20,50);

    plot1->enableAxis(QwtPlot::xBottom,true);
    plot2->enableAxis(QwtPlot::xBottom,false);
    plot2->setGeometry(100,100,640,480);
    plot2->show();
    redrawLayout(plot2,plot1,layout);
}

void redrawLayout(QwtPlot * plot2,QwtPlot * plot1 ,QVBoxLayout * layout){
    QRect plot2_geoCanvas=plot2->canvas()->geometry();
    QRect plot1_geoCanvas=plot1->canvas()->geometry();
    QRect layout_geo= layout->geometry();
    layout->setContentsMargins(37,100,100,100);

    int mm1=plot1->canvas()->heightMM();
    int mm2=plot2->canvas()->heightMM();

    double la1=50.0*(mm2-2.0*100/3.0)/70.0;
    double lb1=la1+100.0/3.0;
    double yb1=50.0*lb1/la1;

    double la2=abs(-20.0)*(mm2-2*100.0/3.0)/70.0;
    double lb2=la2+100.0/3.0;
    double yb2=-20.0*lb2/la2;

    plot2->setAxisScale(QwtPlot::yLeft,yb2,yb1);
    plot2->setGeometry(100,100,640,480);
}
In der Funktion redrawLayout() werden die min/max werte für das plot2 neu bestimmt. Wie es aus der Abbildung zu sehen ist fallen die Achsen nicht zusammen. Das hängt wahlscheinlich an der falsch ausgelesenen Höhe der Achse (plot1->canvas()->heightMM();). Ich habe schon diverse andere Methoden ausprobiert um die Höhe der Achse zu bestimmen:

1) über QwtScaleWidget
2) canvas->geometry
3) plot->geometry
4) QwtScaleDraw hier über die Funktion length

all das führt nicht zu dem gewünschten Ergebnis. Weiß jemand wie man die Länge der Achsenlinie, und zwar hier von -20 bis 50, oder am besten die gesamte Position der Achse auslesen kann? Vielleicht gibt es auch eine andere Vorgehensweise, an die noch nicht gedacht habe?

Vielen Dank für die Hilfe schon im voraus.
Dateianhänge
ScreenShot001.png
SimpleScreenShot
ScreenShot001.png (63.95 KiB) 6899 mal betrachtet

Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Re: Achsen von QwtPlot

Beitrag von Uwe » 5. Juli 2013 14:56

Die Position von Plot Koordinate 0 als Widget Koordinate ( der Plot Canvas != Plot ) bekommst Du mit: "qRound( plot->canvasMap( QwPlot::yLeft ).transform( 0 ) ) );"
Die Canvas ist ein direktes Kind vom Plot Widget, also einfach "plot->canvas().y()" drauf addieren und Du hast die Position relativ zum Plot Widget.

Vorsicht aber mit dem Zeitpunkt an dem Du die Berechnung durchführst. Änderungen der Achse werden erst nach dem nächsten replot wirksam und die Position verändert sich natürlich mit jedem resizeEvent.

Uwe

Antworten