PDA

View Full Version : Random markers from nowhere.



Spitfire
1st November 2011, 13:45
Hey.

I've a plot with a curve and a bunch of markers on it.
When zooming in sometimes I get some random markers apearing.
7059

Points with text are added by me, all other points appear from somewhere.

I have no idea why it's happening. Maybe I'm missing some zoomer setting?

Anyway, I've created simple example app to demonstrate the issue:

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>

class QwtPlot;
class QwtPlotZoomer;

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);
~MainWindow();

private:
void addCurve( void );
void addMarkers( void );

QwtPlot* plot;
QwtPlotZoomer* zoomer;

QVector<double> x;
QVector<double> y;
};

#endif // MAINWINDOW_H


// mainwindow.cpp
#include "mainwindow.h"

#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_marker.h>
#include <qwt_symbol.h>
#include <qwt_plot_zoomer.h>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->plot = new QwtPlot(this);
this->zoomer = new QwtPlotZoomer(this->plot->canvas());

this->addCurve();
this->addMarkers();

this->zoomer->setZoomBase();;
this->setCentralWidget(this->plot);
}

MainWindow::~MainWindow()
{

}

void MainWindow::addCurve( void )
{
int count = 20000;

for(int i = 0; i < count; ++i)
{
this->x.append(i);
this->y.append(i);
}

QwtPlotCurve* curve = new QwtPlotCurve();
curve->setRawData(this->x.constBegin(), this->y.constBegin(), this->x.size());
curve->attach(this->plot);
}

void MainWindow::addMarkers( void )
{
int count = 5000;
int step = this->x.size()/count;

for(int i = 0; i < count; ++i)
{
int x = i*step;
int y = this->y[x];

QwtPlotMarker* m = new QwtPlotMarker();
m->setSymbol(QwtSymbol(QwtSymbol::Ellipse, QBrush(Qt::red), QPen(Qt::red), QSize(5,5)));
m->setValue(x, y);
m->setLabel(QString("%1x%2").arg(x).arg(y));

m->attach(this->plot);
}
}

Any suggestions how to get rid of that UFOs are welcome.

PS: I'm running w7 64 bit with qt 4.6.3 and qwt 5.2.0.

Spitfire
2nd November 2011, 09:03
Ah, I forgot to add that it doesn't happen every time you zoom in.
The more markers and/or deeper you zoom the more likely it will happen but sometimes you have to try several times to see it.

Spitfire
2nd November 2011, 13:07
I've just tested 6.0.1 - the same issue :(

Any idea how to solve it?

ars
2nd November 2011, 20:21
Did you also look at the Y scale? It shows negative values which is rather surprising when zooming into a trace consisting of positive values only.
I've tried to reproduce the behavior in my environment (linux 64 Bit + qwt 5.1.1), but had no luck.

With my application I ran into a similar behavior with deep zooming some time ago. Here the reason was an integer overflow in my overwrite of the plot curve class (overwriting the drawLines() method).

Spitfire
3rd November 2011, 11:04
Thank for the answer!

The nevagive Y value is there because the curve on the image goes from +300 to -300.
The example provided doesn't have negative values and the same happens.

I will try it on linux later today just to make sure.
Sometimes you have to zoom in (deep) several times to see the extra markers.
I can get them almost every time, and the more complex curve is the easier to reproduce it.

At the beggining I also though that I've messed something up but it happens with clean project so that's not it.

I hope that the issue can be resolved as it's a show stopper in the project I work on now ;/

Added after 1 29 minutes:

I've checked linux build and it seems fine.

I've also checked Qt 4.7.4 on windows and issue is still there.

I've updated the example so now you don't have to look for places where it occurs, just click buttons on the top and plot will zoom to where I've found alien markers to be.
Note: every marker without text is something that should not be there.


//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>

class QwtPlot;
class QwtPlotZoomer;

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void zoom1( void );
void zoom2( void );
void zoom3( void );
void zoom4( void );
void zoom5( void );
void zoom6( void );

private:
void addCurve( void );
void addMarkers( void );

QwtPlot* plot;
QwtPlotZoomer* zoomer;

QVector<double> x;
QVector<double> y;
};

#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"

#include <QToolBar>

#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_marker.h>
#include <qwt_symbol.h>
#include <qwt_plot_zoomer.h>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QToolBar* tb = this->addToolBar("");
tb->addAction("Zoom1", this, SLOT(zoom1()));
tb->addAction("Zoom2", this, SLOT(zoom2()));
tb->addAction("Zoom3", this, SLOT(zoom3()));
tb->addAction("Zoom4", this, SLOT(zoom4()));
tb->addAction("Zoom5", this, SLOT(zoom5()));
tb->addAction("Zoom6", this, SLOT(zoom6()));

this->plot = new QwtPlot(this);
plot->setFixedSize(800, 600);

this->zoomer = new QwtPlotZoomer(this->plot->canvas());

this->addCurve();
this->addMarkers();

this->zoomer->setZoomBase();;
this->setCentralWidget(this->plot);
}

MainWindow::~MainWindow()
{
}

void MainWindow::zoom1( void )
{
this->zoomer->zoom(QRectF(QPointF(7262.49, 7256.79), QSizeF(15.8157, 29.976)));
}

void MainWindow::zoom2( void )
{
this->zoomer->zoom(QRectF(QPointF(11794, 11794.6), QSizeF(12.9803, 12.4409)));
}

void MainWindow::zoom3( void )
{
this->zoomer->zoom(QRectF(QPointF(9975.49, 9973.82), QSizeF(1.379,4.97203)));
}

void MainWindow::zoom4( void )
{
this->zoomer->zoom(QRectF(QPointF(9555.91, 9556.03), QSizeF(0.2, 0.3525673)));
}

void MainWindow::zoom5( void )
{
this->zoomer->zoom(QRectF(QPointF(7931.51, 7931.44), QSizeF(0.951209, 0.998621)));
}

void MainWindow::zoom6( void )
{
this->zoomer->zoom(QRectF(QPointF(3357.88, 15976.8), QSizeF(142.687, 550.418)));
}

void MainWindow::addCurve( void )
{
int count = 20000;

for(int i = 0; i < count; ++i)
{
this->x.append(i);
this->y.append(i);
}

QwtPlotCurve* curve = new QwtPlotCurve();
curve->setData(this->x.constBegin(), this->y.constBegin(), this->x.size());
curve->attach(this->plot);
}

void MainWindow::addMarkers( void )
{
int count = 5000;
int step = this->x.size()/count;

for(int i = 0; i < count; ++i)
{
int x = i*step;
int y = this->y[x];

QwtPlotMarker* m = new QwtPlotMarker();
m->setSymbol(QwtSymbol(QwtSymbol::Ellipse, QBrush(Qt::red), QPen(Qt::red), QSize(5,5)));
m->setValue(x, y);
m->setLabel(QString("%1x%2").arg(x).arg(y));

m->attach(this->plot);
}
}

Any suggestions what is a cause of this behaviour?

Uwe
3rd November 2011, 11:32
First of all simplify your code:

a) throw away the zoomer and set the scales to an area, where you have problems using: QwtPlot::setAxisScale
b) attach only one type of plot item ( curve or markers )


After you have eliminated one type of plot item: which one is the reason for the problem ( when only markers are left remove your vectors too ) ?
What happens when using "-graphicssystem raster" on your linux box ?
What exactly is wrong in your screenshot: the lines, the text labels, the symbols or whatever do you mean by aliens ? Didn't check your code in detail, but as the markers have different coordinates as the curve points - is it about the text labels ?



When you have sorted these thing s out, we can continue to debug the details,

Uwe

Spitfire
3rd November 2011, 13:49
Hey Uve,

From what I see the problem seems to be somewhere around QwtSymbol::Ellipse.
When I change it to rect, everything is fine.

But going back:
- using '-graphicssystem raster' on linux box doesn't seem to make any difference - everything is still fine.
- I've simplified the code to have just single marker:
//mainwindow.cpp
#include "mainwindow.h"

#include <QToolBar>
#include <QDebug>

#include <qwt_plot.h>
#include <qwt_plot_marker.h>
#include <qwt_symbol.h>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QToolBar* tb = this->addToolBar("");
tb->addAction("Zoom (~7262x7256)", this, SLOT(zoom()));
tb->addAction("Reset", this, SLOT(reset()));

this->plot = new QwtPlot(this);
plot->setFixedSize(800, 600);
this->setCentralWidget(this->plot);

this->addMarker();
this->reset();
}

MainWindow::~MainWindow()
{
}

void MainWindow::zoom( void )
{
this->plot->setAxisScale(QwtPlot::xBottom, 7262.49, 7262.49+15.8157);
this->plot->setAxisScale(QwtPlot::yLeft, 7256.79, 7256.79+29.976);
this->plot->replot();
}

void MainWindow::reset( void )
{
this->plot->setAxisScale(QwtPlot::xBottom, 0, 10000);
this->plot->setAxisScale(QwtPlot::yLeft, 0, 10000);
this->plot->replot();
}

void MainWindow::addMarker( void )
{
QwtPlotMarker* m = new QwtPlotMarker();
m->setSymbol(QwtSymbol(QwtSymbol::Ellipse, QBrush(Qt::red), QPen(Qt::red), QSize(5,5)));
m->setValue(280, 280);
m->setLabel(QString("%1x%2").arg(280).arg(280));
m->attach(this->plot);
}
The scale is set to 0-10000 on both X and Y axis.
There's only one marker at 280x280 with some text (to distinguish it from the alien one).
Zoom button zooms into certain area: top left: 7262.49x7256.79 size: 15.8157x29.976.
When you zoom in you can see marker symbol in a place where it should be nothing.

Here's a sceenshot before zooming, you can see a marker with some text at 280x280 position:
7070
And here's a screenshot after zooming, you can see a marker with no text at around 7274x7272.
7071

I think that for some reason (bug in Qwt/Qt? int overflow?) Ellipse symbol is drawn in wrong place.
I'm testing it with Qwt 5.2.0 (Qt 4.6.3, w7 64bit) and this particular point I've chosen will probably fail to show the problem with different version but it happens with other versions as well for different points.

So any ideas why this symbol appears where it should not?

Uwe
3rd November 2011, 14:13
Next step is to start your debugger ( or add some debug statements ) and check the rectangle ( this is in widget coordinates ) in QwtPainter::drawEllipse.

What are the coordinates ?

Uwe

Spitfire
3rd November 2011, 14:27
Done that some time ago but it seems fine to me, rectangle is far outside visible area.:

Drawing Ellipse: QRect(-327141,131369 4x4) (reported by QwtPainter::drawEllipse() ).


In fact I've done much simpler example using Qt only:
void MainWindow::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.setBrush(Qt::red);
p.drawEllipse(QPointF(-327650.0, 131100.0), 10.0, 10.0);
}

This will draw black (!) ellipse around top left corner of the window.

Qt bug?

Uwe
3rd November 2011, 14:35
Well then change the implementation of QwtPlotMarker::draw this way:


void QwtPlotMarker::draw( QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
const QRectF &canvasRect ) const
{
const QPointF pos( xMap.transform( d_data->xValue ),
yMap.transform( d_data->yValue ) );

// draw lines

drawLines( painter, canvasRect, pos );

if ( canvasRect.contains( pos ) )
{
// draw symbol
if ( d_data->symbol &&
( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
{
d_data->symbol->drawSymbol( painter, pos );
}

drawLabel( painter, canvasRect, pos );
}
}

Uwe

Spitfire
3rd November 2011, 14:43
I may do that.
Thanks for suggestion.

I'm surprised to find something like that.
Anyway, I know what to do now, At least I can proceed further :)

Thanks again guys!