QCustomPlot技术操作:已有绘图加散点及按X值取Y值绘图
Hey there! Let's break down your two QCustomPlot questions with practical code examples, building off your existing createPlot() function.
To add scatter points above your already-created plot, you'll need to create a dedicated QCPGraph (or repurpose an existing one) to hold the scatter data, define a distinct scatter style, and then refresh the plot. Here's how to implement it:
Example Code
void Qt_PlotTest::addScatterPoints(QCustomPlot* customPlot) { // Create a new graph to hold scatter points (keeps your original plot intact) QCPGraph* scatterGraph = customPlot->addGraph(); // Define your scatter style: red circles, size 8 QCPScatterStyle scatterStyle(QCPScatterStyle::ssCircle); scatterStyle.setColor(Qt::red); scatterStyle.setSize(8); scatterGraph->setScatterStyle(scatterStyle); // Hide the line for this graph (we only want to see scatter points) scatterGraph->setLineStyle(QCPGraph::lsNone); // Prepare your scatter data (adjust X/Y values to match your use case) double now = QDateTime::currentDateTime().toTime_t(); QVector<double> scatterX, scatterY; scatterX << now - 7200 << now - 3600 << now; // 2 hours ago, 1 hour ago, now scatterY << 45 << 60 << 70; // Corresponding Y values for your scatter points // Assign data and refresh the plot scatterGraph->setData(scatterX, scatterY); customPlot->rescaleAxes(true); // Optional: auto-adjust axes to fit new points customPlot->replot(); }
How to Use It
Call this function after your createPlot() function finishes initializing the plot, or trigger it from a user action (like a button click):
// Inside your createPlot() function, after setting up the main plot addScatterPoints(customPlot);
If you want to pull Y values corresponding to specific X values from your existing plot data, you can use QCPGraph's built-in search methods, or interpolate values if your target X isn't an exact match in the original data. Here's a step-by-step implementation:
Example Code
void Qt_PlotTest::plotPointsFromExistingX(QCustomPlot* customPlot) { // Get your main plot graph (assuming it's the first graph at index 0) QCPGraph* mainGraph = customPlot->graph(0); if (!mainGraph) return; // Exit if no main plot exists // Define the X values you want to look up double now = QDateTime::currentDateTime().toTime_t(); QVector<double> targetXValues = {now - 7200, now - 3600, now}; QVector<double> plotX, plotY; for (double targetX : targetXValues) { // Find the first data point with an X value >= targetX int dataIndex = mainGraph->findBegin(targetX, true); if (dataIndex >= 0 && dataIndex < mainGraph->data()->size()) { // Case 1: Exact X value match if (qFuzzyCompare(mainGraph->data()->at(dataIndex)->key, targetX)) { plotX << targetX; plotY << mainGraph->data()->at(dataIndex)->value; } // Case 2: Interpolate Y value if X is between two existing points else if (dataIndex > 0) { double x1 = mainGraph->data()->at(dataIndex - 1)->key; double y1 = mainGraph->data()->at(dataIndex - 1)->value; double x2 = mainGraph->data()->at(dataIndex)->key; double y2 = mainGraph->data()->at(dataIndex)->value; // Linear interpolation to get approximate Y value double interpolatedY = y1 + (y2 - y1) * (targetX - x1) / (x2 - x1); plotX << targetX; plotY << interpolatedY; } } } // Create a graph to draw these points QCPGraph* lookupPointsGraph = customPlot->addGraph(); QCPScatterStyle pointStyle(QCPScatterStyle::ssSquare); pointStyle.setColor(Qt::darkBlue); pointStyle.setSize(10); lookupPointsGraph->setScatterStyle(pointStyle); lookupPointsGraph->setLineStyle(QCPGraph::lsNone); // Assign data and refresh lookupPointsGraph->setData(plotX, plotY); customPlot->replot(); }
Key Notes
qFuzzyCompareis used to compare floating-point X values safely (avoids precision issues).- Linear interpolation is useful if your target X doesn't exactly match any point in the original dataset.
- If you don't want to create a new graph every time, you can initialize a single scatter graph once and update its data with
setData()later.
内容的提问来源于stack exchange,提问作者remi

