Dear Experts:
I desire to plot a lot of real-time data in qcustomplot. But I encountered a problem that as time went by, the plot data become larger and larger so that the qcustomplot used much CPU resource because the graph had to redraw all data received before when the function replot() is used. Besides, I must use four qcustomplot in one UI so usage rate of CPU is really high. So I tried to modify the replot way. I defined a flag called dontclearflag in QCPLayer. If this flag is set to be true, replot way become step by step drawing which means that the painter only draws data that is new. I reimplemented the clipRect() function in QCPGraph. The code is as below.

QRect QCPGraph::clipRect() const//virtual function inplemented by zouyi. This function is used to set plotting area.
{
    if(newDataContainer->isEmpty())
    if(layer()->dontClearFlag==false)//added by zouyi.If flag is false,plotting way redraw all data is used.Else we use plotting way that draw data step by step.
  if (mKeyAxis && mValueAxis)
    return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect();
  else
    return QRect();
    else
    {
        if(newDataContainer->isEmpty())//if we don't get new data,we skip drawing.
        {
            QRect r(0,0,0,0);
            return r;
        }
        else
        {
            double x;
            double y;
            bool foundrange;
            coordsToPixels(newDataContainer->constBegin()->key,newDataContainer->valueRange(foundrange).upper,x,y);
            double x1;
            double y1;
            coordsToPixels(newDataContainer->constEnd()->key,newDataContainer->valueRange(foundrange).lower,x1,y1);
            int length_of_cliprect=int(x1-x);
            int height_of_cliprect=int(y-y1);
            return QRect(int(x-1),int(y-1),length_of_cliprect+1,height_of_cliprect+1);//need to be modified
        }
    }    
}

Then I modified function getoptimizedScatterdata(). The code is as below.
void QCPGraph::getOptimizedScatterData(QVector<QCPGraphData> *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const
{
  if (!scatterData) return;
  QCPAxis *keyAxis = mKeyAxis.data();
  QCPAxis *valueAxis = mValueAxis.data();
  if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
  
  const int scatterModulo = mScatterSkip+1;
  const bool doScatterSkip = mScatterSkip > 0;
  int beginIndex = begin-mDataContainer->constBegin();
  int endIndex = end-mDataContainer->constBegin();
  while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter
  {
    ++beginIndex;
    ++begin;
  }
  if (begin == end) return;
  int dataCount = end-begin;
  int maxCount = std::numeric_limits<int>::max();
  if(layer()->dontClearFlag==false)//added by zouyi
  {
  if (mAdaptiveSampling)
  {
    int keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key));
    maxCount = 2*keyPixelSpan+2;
  }
  
  if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average
  {
    double valueMaxRange = valueAxis->range().upper;
    double valueMinRange = valueAxis->range().lower;
    QCPGraphDataContainer::const_iterator it = begin;
    int itIndex = beginIndex;
    double minValue = it->value;
    double maxValue = it->value;
    QCPGraphDataContainer::const_iterator minValueIt = it;
    QCPGraphDataContainer::const_iterator maxValueIt = it;
    QCPGraphDataContainer::const_iterator currentIntervalStart = it;
    int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction
    int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey
    double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound));
    double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates
    bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes)
    int intervalDataCount = 1;
    // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect:
    if (!doScatterSkip)
      ++it;
    else
    {
      itIndex += scatterModulo;
      if (itIndex < endIndex) // make sure we didn't jump over end
        it += scatterModulo;
      else
      {
        it = end;
        itIndex = endIndex;
      }
    }
    // main loop over data points:
    while (it != end)
    {
      if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary
      {
        if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange)
        {
          minValue = it->value;
          minValueIt = it;
        } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange)
        {
          maxValue = it->value;
          maxValueIt = it;
        }
        ++intervalDataCount;
      } else // new pixel started
      {
        if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them
        {
          // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot):
          double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue));
          int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average
          QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart;
          int c = 0;
          while (intervalIt != it)
          {
            if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange)
              scatterData->append(*intervalIt);
            ++c;
            if (!doScatterSkip)
              ++intervalIt;
            else
              intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here
          }
        } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange)
          scatterData->append(*currentIntervalStart);
        minValue = it->value;
        maxValue = it->value;
        currentIntervalStart = it;
        currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound));
        if (keyEpsilonVariable)
          keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
        intervalDataCount = 1;
      }
      // advance to next data point:
      if (!doScatterSkip)
        ++it;
      else
      {
        itIndex += scatterModulo;
        if (itIndex < endIndex) // make sure we didn't jump over end
          it += scatterModulo;
        else
        {
          it = end;
          itIndex = endIndex;
        }
      }
    }
    // handle last interval:
    if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them
    {
      // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot):
      double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue));
      int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average
      QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart;
      int intervalItIndex = intervalIt-mDataContainer->constBegin();
      int c = 0;
      while (intervalIt != it)
      {
        if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange)
          scatterData->append(*intervalIt);
        ++c;
        if (!doScatterSkip)
          ++intervalIt;
        else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison:
        {
          intervalItIndex += scatterModulo;
          if (intervalItIndex < itIndex)
            intervalIt += scatterModulo;
          else
          {
            intervalIt = it;
            intervalItIndex = itIndex;
          }
        }
      }
    } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange)
      scatterData->append(*currentIntervalStart);
    
  } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output
  {
    QCPGraphDataContainer::const_iterator it = begin;
    int itIndex = beginIndex;
    scatterData->reserve(dataCount);
    while (it != end)
    {
      scatterData->append(*it);
      // advance to next data point:
      if (!doScatterSkip)
        ++it;
      else
      {
        itIndex += scatterModulo;
        if (itIndex < endIndex)
          it += scatterModulo;
        else
        {
          it = end;
          itIndex = endIndex;
        }
      }
    }
  }
  }
  else if(!newDataContainer->isEmpty())//added by zouyi
  {
      QCPGraphDataContainer::const_iterator it = newDataContainer->constBegin();
      end=newDataContainer->constEnd()+1;
      scatterData->reserve(end-it+3);
      while (it != end)
      {
        scatterData->append(*it);
        // advance to next data point:
      }
    }
  else
  return;
  newDataContainer->clear();
}

I set dontclearflag to true and replot once for per 2 seconds. But data showed on screen blinked. It showed for 2 seconds then all disappeared. After a while all data showed for another 2 seconds. I don't know why it disappears.