PDA

View Full Version : How to situate the second QwtPlot under the first QwtPlot smoothly???



dqrest
22nd October 2012, 09:44
Hi)I have two QwtyPlots A and B. I set A and B into the QGridLayout. QwtPlot B is under the QwtPlot A. The yAxi's of QwtPlot A belongs to (1000000;90000000) and yAxis of QwtPlot B to (1;10), that's why the left edges of qwtplots are not smoothly((((How can I do it???Please, help!I saw the example plotmatrix and didn't find there the decision!!!

Uwe
22nd October 2012, 12:57
I saw the example plotmatrix and didn't find there the decision!!!
The basic idea is to assign a fixed extent for all y axes calculated from the maximum needed extent.

You find the code in this example.
Uwe

dqrest
24th October 2012, 15:44
How can I assign a fixed extent for all y axes???Please, give me an example))

wysota
24th October 2012, 16:12
Iterate over scale draw's of y axis of all plots, get their extents, calculate the maximum and then iterate over all plots again setting that maximum as a minimum extent. You can see how to do it in the plotmatrix Qwt example.

bigjoeystud
24th October 2012, 17:23
Unfortunately, this approach doesn't work when you have labels on the axis. I'm not exactly sure why. We need a new layout algorithm which understands how to really lay plots beside or next to one another.

Consider the following diff:


Index: plotmatrix/plotmatrix.cpp
================================================== =================
--- plotmatrix/plotmatrix.cpp (revision 1474)
+++ plotmatrix/plotmatrix.cpp (working copy)
@@ -47,6 +47,9 @@
QwtPlot *plot = new QwtPlot( this );
layout->addWidget( plot, row, col );

+if (row == 0 && col == 0) plot->axisWidget (QwtPlot::yLeft)->setTitle ("Line 1");
+if (row == 1 && col == 0) plot->axisWidget (QwtPlot::yLeft)->setTitle ("Line 1<BR>Units");
+
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
connect( plot->axisWidget( axis ),


Are there other ideas? I find I can get it close sometimes, but I never quite it completely right regardless of what I try when I have varying labels on the axes, and varying limits on the axes.

Cheers,
Joey

wysota
24th October 2012, 18:22
This works:

================================================== =================
--- plotmatrix.cpp (revision 1452)
+++ plotmatrix.cpp (working copy)
@@ -47,6 +47,9 @@
QwtPlot *plot = new QwtPlot( this );
layout->addWidget( plot, row, col );

+ if (row == 0 && col == 0) plot->axisWidget (QwtPlot::yLeft)->setTitle ("Line 1");
+ if (row == 1 && col == 0) plot->axisWidget (QwtPlot::yLeft)->setTitle ("Line 1<BR>Units");
+
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
connect( plot->axisWidget( axis ),
@@ -276,7 +279,9 @@
QwtScaleDraw *sd = scaleWidget->scaleDraw();
sd->setMinimumExtent( 0.0 );

- const double extent = sd->extent( scaleWidget->font() );
+ double extent = sd->extent( scaleWidget->font() );
+ if( !scaleWidget->title().isEmpty())
+ extent += scaleWidget->title().textSize().height();
if ( extent > maxExtent )
maxExtent = extent;
}
@@ -287,7 +292,11 @@
if ( p )
{
QwtScaleWidget *scaleWidget = p->axisWidget( axis );
- scaleWidget->scaleDraw()->setMinimumExtent( maxExtent );
+ double extent = maxExtent;
+ if(!scaleWidget->title().text().isEmpty()) {
+ extent -= scaleWidget->title().textSize().height();
+ }
+ scaleWidget->scaleDraw()->setMinimumExtent( extent );
}
}
}

Of course in a general case you have to take into account the font of the title, which I ignored assuming it is the default one. You should also consider the spacing between the title and the scale (you can see there is an "off by 1" (or 2) error in the result of my patch).

bigjoeystud
25th October 2012, 18:28
Thanks for that! I wasn't using textSize so I was getting different answers. One more thing is if there is a legend on only one side, there will be a misalignment, even using the logic of adding/subtracting. Is there a way to correct for that?

Here's a diff:



Index: plotmatrix/plotmatrix.cpp
================================================== =================
--- plotmatrix/plotmatrix.cpp (revision 1477)
+++ plotmatrix/plotmatrix.cpp (working copy)
@@ -14,6 +14,9 @@
#include <qwt_plot.h>
#include <qwt_scale_widget.h>
#include <qwt_scale_draw.h>
+#include <qwt_plot_curve.h>
+#include <qwt_plot_layout.h>
+#include <qwt_legend.h>
#include "plotmatrix.h"

class PlotMatrix::PrivateData
@@ -47,6 +50,30 @@
QwtPlot *plot = new QwtPlot( this );
layout->addWidget( plot, row, col );

+if (row == 0 && col == 0) plot->axisWidget (QwtPlot::yLeft)->setTitle ("Hello!");
+if (row == 1 && col == 0) plot->axisWidget (QwtPlot::yLeft)->setTitle ("Hello!<BR>Units");
+if (row == 1 && col == 3) {
+ QVector <QPointF> data;
+ data.push_back (QPointF (-420, 10));
+ data.push_back (QPointF (940, -10));
+ QwtPlotCurve *curve = new QwtPlotCurve ("data");
+ curve->setSamples (data);
+ curve->setPen( QPen( Qt::cyan ) );
+ curve->attach (plot);
+ // legend
+ QwtLegend *legend = new QwtLegend;
+ plot->insertLegend( legend, QwtPlot::RightLegend );
+}
+
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
connect( plot->axisWidget( axis ),
@@ -276,7 +303,13 @@
QwtScaleDraw *sd = scaleWidget->scaleDraw();
sd->setMinimumExtent( 0.0 );

- const double extent = sd->extent( scaleWidget->font() );
+ double extent = sd->extent( scaleWidget->font() );
+ if( !scaleWidget->title().isEmpty())
+ extent += scaleWidget->title().textSize().height();
+ if (p->legend () && axis == p->plotLayout ()->legendPosition ()) {
+ double legendSize = p->legend ()->sizeHint ().width ();
+ extent += legendSize;
+ }
if ( extent > maxExtent )
maxExtent = extent;
}
@@ -287,7 +320,16 @@
if ( p )
{
QwtScaleWidget *scaleWidget = p->axisWidget( axis );
- scaleWidget->scaleDraw()->setMinimumExtent( maxExtent );
+ double extent = maxExtent;
+ if(!scaleWidget->title().text().isEmpty()) {
+ extent -= scaleWidget->title().textSize().height();
+ }
+
+ if (p->legend () && axis == p->plotLayout ()->legendPosition ()) {
+ double legendSize = p->legend ()->sizeHint ().width ();
+ extent -= legendSize;
+ }
+ scaleWidget->scaleDraw()->setMinimumExtent( extent );
}
}
}

wysota
25th October 2012, 20:36
You have to compensate for whatever decoration/primitive you want to be dynamic the same way I compensated for the axis title. If you have a legend, take it into consideration when calculating the extent.

bigjoeystud
25th October 2012, 20:41
Yes! I did that (even in the above diff); however, it is still off by 1 or 2. For some reason, the legend size that I get from p->legend ()->sizeHint () is not quite right. There is a margin or spacing of some sort, but trying to compensate for that similarly does seem to work. I keep thinking sizeHint isn't the right way to go about this, but I don't see other alternatives.

wysota
25th October 2012, 20:55
sizeHint() is probably ok but there is certainly some spacing involved. Look into Qwt source code to see how to calculate everything.