How to reset x and y axis in qcustomplot after replotting (Qt) - c++

I am trying to crop my data, and replot only a selected part of the graph, but after the replot, the x axis still has the same values, and my graph starts at (0,0) instead of (cropped_starting_value_x, y).
How can I reset the values of the X axis? I've already tryed rescaleaxes, but it's not working.
Here I only have values from around 19 seconds.
QCPGraph *mainGraph = Customplott[0]->addGraph();
QCPGraph *SecondaryGraph = Customplott[0]->addGraph();
//QCPGraph *TertiaryGraph = Customplott[Number]->addGraph();
//mainGraph->setAdaptiveSampling(true);
mainGraph->setData(Time_temp, Measured_temp);
mainGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone, QPen(Qt::red), QBrush(Qt::white), 3));
mainGraph->setPen(QPen(Qt::blue)); // Magic only happens, when line width == 1
SecondaryGraph->setData(Time_temp, Output_temp);
SecondaryGraph->setPen(QPen(Qt::red));
Customplott[0]->setObjectName("YawRate");
Customplott[0]->xAxis->setLabel("Time [s]");
Customplott[0]->yAxis->setLabel("Yaw Rate");
/* rescale axes according to graph's data */
Customplott[0]->rescaleAxes();
mainGraph->rescaleAxes();
SecondaryGraph->rescaleAxes(true);
Customplott[0]->replot();
Every kind of help is highly appreciated!

You should use this method:
Customplott[0]->xAxis->setRange(minX, maxX);
(documentation here)

Related

How to draw graph for a trajectory which goes left and right in x axis?

i want to draw a trajectory in x and y of a car in a parking lot.
the trajectory in x is not always in the same direction. sometime the car will go left.
the problem here is: sometime (not always!) the graph will no go left in x axis. You can see the two different result on the image https://imgur.com/Z53fNkt
any idea why?
the image at left is what i expect. at right is the same values , but i continue to plot data a little longer.
void TrackingResultsView::setupTrajectoryPlot()
{
QCustomPlot *customPlot = ui->qcp_trajectory;
customPlot->xAxis2->setVisible(true);
customPlot->xAxis2->setLabel("X-Position (pixel)");
customPlot->xAxis2->setRange(0, mModelPtr->frameSize().width());
customPlot->xAxis2->grid()->setVisible(true);
customPlot->xAxis->setRange(0, mModelPtr->frameSize().width());
customPlot->yAxis->setLabel("Y-Position (pixel)");
customPlot->yAxis->setRange(0, mModelPtr->frameSize().height());
customPlot->yAxis->setRangeReversed(true);
customPlot->yAxis2->setVisible(true);
customPlot->yAxis2->setRange(0, mModelPtr->frameSize().height());
customPlot->yAxis2->grid()->setVisible(true);
customPlot->yAxis2->setRangeReversed(true);
customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis);
QVector<QVector<double>> data = createDataMap(mModelPtr->points());
customPlot->graph()->setData(data.at(0), data.at(1), true);
setTheme(customPlot, false);
}
thank you
(english is not my first langage)
The QCPGraph seems to be used for sorted data with only value per key. From QCustomPlot documentation, it looks like the QCPCurve would be a better match in order to plot a trajectory graph (multiple value for the same key).
From the QCPCurve description:
Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, so their visual representation can have loops. This is realized by introducing a third coordinate t, which defines the order of the points described by the other two coordinates x and y.
here my new code with olivier help. its work!
QCustomPlot *customPlot = ui->qcp_trajectory;
customPlot->xAxis2->setVisible(true);
customPlot->xAxis2->setLabel("X-Position (pixel)");
customPlot->xAxis2->setRange(0, mModelPtr->frameSize().width());
customPlot->xAxis2->grid()->setVisible(true);
customPlot->xAxis->setRange(0, mModelPtr->frameSize().width());
customPlot->yAxis->setLabel("Y-Position (pixel)");
customPlot->yAxis->setRange(0, mModelPtr->frameSize().height());
customPlot->yAxis->setRangeReversed(true);
customPlot->yAxis2->setVisible(true);
customPlot->yAxis2->setRange(0, mModelPtr->frameSize().height());
customPlot->yAxis2->grid()->setVisible(true);
customPlot->yAxis2->setRangeReversed(true);
customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis);
// create empty curve objects:
QCPCurve *trajectory = new QCPCurve(customPlot->xAxis2, customPlot->yAxis);
// generate the curve data points:
const int pointCount = mModelPtr->points().size();
QVector<QCPCurveData> datatrajectory(pointCount);
QVector<QVector<double>> data = createDataMap(mModelPtr->points());
for (int i = 0; i < pointCount ; ++i)
{
datatrajectory[i] = QCPCurveData(i, data.at(0).at(i), data.at(1).at(i));
}
trajectory->data()->set(datatrajectory, true);
setTheme(customPlot, false);

Set interval for X and Y QwtPlotZoneItem

I need to plot a region on a graph using the QwtPlotZoneItem class. I need to set different intervals for both X and Y axes, how can I do that?
The orientation of my QwtPlotZoneItem is vertical, so based on the documentation, if I set the interval it will by applied to the X axis only.
"For a horizontal zone the interval is related to the y axis, for a
vertical zone it is related to the x axis."
My constructor sets:
setOrientation( Qt::Vertical );
setInterval( initDate, endDate );
Basically, what I need is to create multiple rectangles on my graph that represents the regions, for example:
Qt 5.3.2
Qwt 6.1.0
I was trying to use an incorrect class for my purposes. I found a note in the documentation:
"For displaying an area that is bounded for x and y coordinates use
QwtPlotShapeItem"
The QwtPlotShapeItem class does exactly what I need.
I need basically to set the brush and create the rectangle, for example:
QwtPlotShapeItem *shapeItem = new QwtPlotShapeItem();
shapeItem->setBrush(QColor(255,255,255, 0));
shapeItem->setPen(QColor(Qt::transparent), 0.0, Qt::SolidLine);
// TopLeft - BottomRight
QRect myRect(QPoint(startDate, yUpperPos), QPoint(endDate, yLowerPos));
shapeItem->setRect( QRectF(myRect) );
shapeItem->attach(myQwtPlot);
myQwtPlot->replot();

Display the plot values on mouse over. - Detect Scatter points

I am attempting to display the plot values of different points on my QCustomPlot in which I have a Line style of lsLine. I know i could set a mouse over signal on the QCustomPlot but that wont really help since I just need to be informed when the mouse is over my plotted line.My question is is there any way to find out if the mouse is over my scatter point. Is there a signal i could connect to that would tell me when the mouse is over a scatter point ?
Reimplement QCustomPlot::mouseMoveEvent or connect to QCustomPlot::mouseMove.
Then use axes' coordToPixel to translate (cursor) pixel coords to plot coords and search nearest points in your QCPDataMap with QMap::lowerBound(cursorX).
You can easily just connect a slot to the mouseMove signal that QCustomPlot emits. You can then use QCPAxis::pixelToCoord to find the coordinate :
connect(this, SIGNAL(mouseMove(QMouseEvent*)), this,SLOT(showPointToolTip(QMouseEvent*)));
void QCustomPlot::showPointToolTip(QMouseEvent *event)
{
int x = this->xAxis->pixelToCoord(event->pos().x());
int y = this->yAxis->pixelToCoord(event->pos().y());
setToolTip(QString("%1 , %2").arg(x).arg(y));
}
when You use datetime format (including more point per second) of X axis, then pixel to coord fails.
If you want to display coordinates between points, then this is the fastest way
maybe usefull (with connected signal QCustomplot::MouseMove)
void MainWindow::onMouseMoveGraph(QMouseEvent* evt)
{
int x = this->ui->customPlot->xAxis->pixelToCoord(evt->pos().x());
int y = this->ui->customPlot->yAxis->pixelToCoord(evt->pos().y());
qDebug()<<"pixelToCoord: "<<data.key<<data.value; //this is correct when step is greater 1 second
if (this->ui->customPlot->selectedGraphs().count()>0)
{
QCPGraph* graph = this->ui->customPlot->selectedGraphs().first();
QCPData data = graph->data()->lowerBound(x).value();
double dbottom = graph->valueAxis()->range().lower; //Yaxis bottom value
double dtop = graph->valueAxis()->range().upper; //Yaxis top value
long ptop = graph->valueAxis()->axisRect()->top(); //graph top margin
long pbottom = graph->valueAxis()->axisRect()->bottom(); //graph bottom position
// result for Y axis
double valueY = (evt->pos().y() - ptop) / (double)(pbottom - ptop)*(double)(dbottom - dtop) + dtop;
//or shortly for X-axis
double valueX = (evt->pos().x() - graph->keyAxis()->axisRect()->left()); //graph width in pixels
double ratio = (double)(graph->keyAxis()->axisRect()->right() - graph->keyAxis()->axisRect()->left()) / (double)(graph->keyAxis()->range().lower - graph->keyAxis()->range().upper); //ratio px->graph width
//and result for X-axis
valueX=-valueX / ratio + graph->keyAxis()->range().lower;
qDebug()<<"calculated:"<<valueX<<valueY;
}
}

Best way to get the nearest intersection point in a grid

I'm using Cocos2D for iPhone to build up a game.I have a grid on the screen drawn by horizontal and vertical lines.(I did it with CCDrawNode) As you might guess there're lots of intersection points in there, I mean the points where horizontal and vertical lines intersect. With every touchBegan-Moved-Ended routine I draw a line, a bolder and different color line. In touchesMoved method I need to find the intersection point nearest to the current end point of the line and stick the line end to that point. How can I do that? I have one idea in my mind which is to add all the intersection points to an array when drawing the grid, iterate through that array and find the closest one. But I think this is not the best approach. You have any better ideas?
Assuming it is a normal grid with evenly spaced lines (e.g. every 10 pixels apart), you are much better off using a formula to tell you where an intersection should be.
E.g. given end point X/Y of 17,23, then x(17)/x-spacing(10) = 1.7, rounds to 2. 2*x-spacing = 20. y/y-spacing=2.3 -> 2*20 = 20. Thus your intersection is 20,20.
EDIT: more detailed example, in C# as that's what I use, if I get time I'll write an Objective-C sample
// defined somewhere and used to draw the grid
private int _spacingX = 10;
private int _spacingY = 10;
public Point GetNearestIntersection(int x, int y)
{
// round off to the nearest vertical/horizontal line number
double tempX = Math.Round((double)x / _spacingX);
double tempY = Math.Round((double)y / _spacingY);
// convert back to pixels
int nearestX = (int)tempX * _spacingX;
int nearestY = (int)tempY * _spacingY;
return new Point(nearestX, nearestY);
}
NOTE: the code above is left quite verbose to help you understand, you could easily re-write it to be cleaner

Find the coordinates of the Corners marked with CornerHarris method in OpenCV for python

I'm trying to find the coordinates of all the shapes that HarrisCorner method marked on my image.
I have it set up so it's marking the correct corners and showing the correct results, but I can't figure out where to find the coordinates after all is said and done.
I need a list of all of the corners that are marked by this algorithm so I can find their area, center of gravity, shape, & size.
Separately I have a list of all of the pixels contained within each shape, so it would be easy for me to match the coordinates with the corresponding shape.
I'm sorry if this is a green question. I've been reading everything I can find. Thank you OpenCV pros!
im = cv.LoadImage("image.jpg")
imgray = cv.LoadImage("image.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
cornerMap = cv.CreateMat(im.height, im.width, cv.CV_32FC1)
cv.CornerHarris(imgray,cornerMap,3)
for y in range(0,imgray.height):
for x in range (0, imgray.width):
harris = cv.Get2D(cornerMap, y, x)
if harris[0] >10e-06:
temp = cv.Circle(im, (x,y),2,cv.RGB(115,0,25))
cv.ShowImage('my window', im)
cv.SaveImage("newimage3.jpg",im)
cv.WaitKey()
The corners are the (x,y) coordinates for which your corner-ness test passes:
if harris[0] > 10e-06