void PolColorMapChart::Init()
{
    QVBoxLayout* layout = new QVBoxLayout(this);
    m_customPlot = new QCustomPlot;
    layout->addWidget(m_customPlot);

    m_width = 16;
    m_height = 8;
    m_colorRange = 1000;

    m_customPlot->xAxis->grid()->setPen(Qt::NoPen);
    m_customPlot->yAxis->grid()->setPen(Qt::NoPen);
    m_customPlot->xAxis->grid()->setSubGridVisible(false);

    m_customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    m_customPlot->yAxis->grid()->setSubGridVisible(true);
    m_customPlot->yAxis->setPadding(5); // a bit more space to the left border
    m_customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
    m_heatmap = new QCPColorMap(m_customPlot->xAxis, m_customPlot->yAxis);  // 构造一个颜色图
    changeChartSize();

    QCPColorScale* colorScale = new QCPColorScale(m_customPlot);  // 构造一个色条
    colorScale->setType(QCPAxis::atRight);   // 右侧垂直显示,与matlab版本一致
    m_customPlot->plotLayout()->addElement(0, 1, colorScale); // 在颜色图右侧显示
    m_heatmap->setColorScale(colorScale);
    QCPColorGradient gradient;  // 色条使用的颜色渐变
    gradient.setColorStopAt(0.0, QColor("#0000ff"));   // 设置色条开始时的颜色
    gradient.setColorStopAt(0.5, QColor("#ffff00"));   // 设置色条开始时的颜色
    gradient.setColorStopAt(1.0, QColor("#ff0000"));  // 设置色条结束时的颜色
    m_heatmap->setGradient(gradient);
    //colorMap->rescaleDataRange();        // 自动计算数据范围,数据范围决定了哪些数据值映射到QCPColorGradient的颜色渐变当中
    m_heatmap->setInterpolate(false);         // 为了显示小方块,我们禁用插值
    setColorRange(m_colorRange);

    // 保持色条与轴矩形边距一致
    QCPMarginGroup* marginGroup = new QCPMarginGroup(m_customPlot);
    m_customPlot->axisRect()->setMarginGroup(QCP::msLeft | QCP::msRight, marginGroup);
    colorScale->setMarginGroup(QCP::msLeft | QCP::msRight, marginGroup);

    //颜色图数据清空
    //m_heatmap->data()->clear();

#if 0
    //测试颜色图接口
    setWidthHeight(16,8);
    setColorRange(1000);
    showColorForTest();
#endif
}

void PolColorMapChart::setWidthHeight(const int width, const int height)
{
    m_width = width;
    m_height = height;
    changeChartSize();
}

void PolColorMapChart::setColorRange(const int colorRange)
{
    m_colorRange = colorRange;
    m_heatmap->setDataRange(QCPRange(0,m_colorRange));
}

void PolColorMapChart::changeChartSize()
{
    m_heatmap->data()->setSize(m_width, m_height);   // 设置颜色图数据维度,其内部维护着一个一维数组(一般表现为二维数组),这里可以理解为有多少个小方块
    // 颜色图在x、y轴上的范围,这里的范围指的是以热力图一个像素点的中间,所以加上0.5就可以显示边缘部分的颜色,所以xy轴的范围也要+1
    m_heatmap->data()->setRange(QCPRange(0.5,m_width + 0.5),QCPRange(0.5, m_height + 0.5));
    m_customPlot->xAxis->setRange(0, m_width + 1);
    m_customPlot->yAxis->setRange(0, m_height + 1);
    m_customPlot->xAxis->ticker()->setTickCount(m_width + 1);
    m_customPlot->yAxis->ticker()->setTickCount(m_height + 1);
    m_customPlot->xAxis->setVisible(false);
    m_customPlot->yAxis->setVisible(false);
}

void PolColorMapChart::addPoints(const QVector<int>& values)
{
    if(values.size() != m_width * m_height)
    {
        return;
    }
    auto* colorMap = static_cast<QCPColorMap*>(m_customPlot->plottable(0));
    int keySize = colorMap->data()->keySize();
    int valueSize = colorMap->data()->valueSize();
    for(int x = 0; x < keySize; ++x)
    {
        for(int y = 0; y < valueSize; ++y)
        {
            int index = x + y * keySize;
            int colorValue =  values.at(index);
            colorMap->data()->setCell(x, valueSize - y - 1, colorValue);
        }
    }
    m_customPlot->replot();
}

在热力图上 点上添加文本说明

首先初始化 

QVector<QCPItemText*> m_vTextItem;
 void PolColorMapChart::changeChartSize()
{
    m_heatmap->data()->setSize(m_width, m_height);   // 设置颜色图数据维度,其内部维护着一个一维数组(一般表现为二维数组),这里可以理解为有多少个小方块
    // 颜色图在x、y轴上的范围,这里的范围指的是以热力图一个像素点的中间,所以加上0.5就可以显示边缘部分的颜色,所以xy轴的范围也要+1
    m_heatmap->data()->setRange(QCPRange(0.5, m_width + 0.5), QCPRange(0.5, m_height + 0.5));
    m_customPlot->xAxis->setRange(0, m_width + 1);
    m_customPlot->yAxis->setRange(0, m_height + 1);


    m_customPlot->xAxis->ticker()->setTickCount(m_width + 1);
    m_customPlot->yAxis->ticker()->setTickCount(m_height + 1);


    m_customPlot->xAxis->setVisible(false);
    m_customPlot->yAxis->setVisible(false);


    int itemSize = m_vTextItem.size();
    for(int i = 0; i < itemSize; i++)
    {
        if(m_vTextItem.at(i))
        {
            m_vTextItem.at(i)->deleteLater();
        }
    }


    m_vTextItem.clear();


    for(int i = 0; i < m_width * m_height; i++)
    {
        QCPItemText* textItem = new QCPItemText(m_customPlot);
        m_vTextItem.append(textItem);
    }
}

添加热力图点时 设置QCPItemText的位置和内容

void PolColorMapChart::addPoints(const QVector<int>& values)
{
    if(values.size() != m_width * m_height)
    {
        return;
    }
    auto* colorMap = static_cast<QCPColorMap*>(m_customPlot->plottable(0));
    int keySize = colorMap->data()->keySize();
    int valueSize = colorMap->data()->valueSize();
    for(int x = 0; x < keySize; ++x)
    {
        for(int y = 0; y < valueSize; ++y)
        {
            int index = x + y * keySize;
            int colorValue =  values.at(index);
            colorMap->data()->setCell(x, valueSize - y - 1, colorValue);


            double coorX;
            double coorY;
            colorMap->data()->cellToCoord(x, valueSize - y - 1, &coorX, &coorY);


            QCPItemText* textItem = m_vTextItem[index];
            int row = index / m_width + 1;
            int col = index % m_width + 1;
            textItem->setText("row:" + QString::number(row) + "\n" +
                              "col:" + QString::number(col) +  "\n" +
                              QString::number(colorValue)
                             );
            textItem->setPositionAlignment(Qt::AlignCenter | Qt::AlignVCenter);
            textItem->setColor(Qt::black);
            textItem->position->setCoords(coorX, coorY);
        }
    }
    m_customPlot->replot();
}