首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++ Qt开发:Charts绘制各类图表详解

C++ Qt开发:Charts绘制各类图表详解

作者头像
王 瑞
发布于 2023-12-26 01:18:01
发布于 2023-12-26 01:18:01
1.9K02
代码可运行
举报
运行总次数:2
代码可运行

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TreeWidgetQCharts的常用方法及灵活运用。

在之前的文章中笔者介绍了如何使用QCharts模块来绘制简单的折线图并对通用API接口进行了概括,本章我们通过在TreeWidget组件中提取数据,并依次实现柱状图、饼状图、堆叠图、百分比图、散点图等。

1.1 创建柱状图

柱状图(Bar Chart)用于显示各类别之间的数量关系。它通过在一个坐标系中绘制垂直的矩形条(柱)来表示数据。每个柱的高度表示相应类别的数量或数值,柱的宽度一般是固定的,类别之间的间隔可以根据需要调整。

柱状图主要用于比较不同类别的数值或数量,帮助观察数据的分布趋势、对比不同类别的数据大小,以及发现数据之间的关系。柱状图通常在横轴上表示不同的类别,纵轴上表示数量或数值。

以下是柱状图的一些主要特点:

  1. 垂直柱状图(Vertical Bar Chart):柱状图的柱是垂直排列的,纵轴表示数值或数量。
  2. 水平柱状图(Horizontal Bar Chart):柱状图的柱是水平排列的,横轴表示数值或数量。
  3. 分组柱状图(Grouped Bar Chart):将柱按照类别分组,同一组内的柱一般在相同的位置。
  4. 堆叠柱状图(Stacked Bar Chart):将柱叠加在一起,柱的高度表示总和。
  5. 百分比柱状图(Percentage Bar Chart):每个柱的高度表示相对于总和的百分比。

柱状图是数据可视化中常用的工具之一,易于理解且能够直观地传达信息。在业务、科学研究、金融等领域,柱状图被广泛用于展示数据的分布和趋势。在Qt中柱状图的绘制离不开三个类的支持,其分别是QBarSetQBarSeriesQBarCategoryAxis这三个类提供了用于操作和管理条形图数据集的方法。

QBarSet类主要用于创建或表示一个柱状图的集合元素。以下是关于QBarSet的主要方法的说明和概述,以表格形式呈现:

方法

描述

QBarSet(const QString &label = QString())

构造函数,创建一个空的 QBarSet 对象,可以通过提供标签进行初始化。

void append(qreal value)

将一个值添加到数据集的末尾。

void append(const QList<qreal> &values)

将一组值添加到数据集的末尾。

void replace(int index, qreal value)

替换数据集中指定索引位置的值。

void replace(const QList<qreal> &values)

用提供的一组值替换整个数据集。

void clear()

清除数据集中的所有值。

int count() const

返回数据集中值的数量。

bool isEmpty() const

检查数据集是否为空。

QString label() const

返回数据集的标签。

void setLabel(const QString &label)

设置数据集的标签。

qreal at(int index) const

返回数据集中指定索引位置的值。

QList<qreal> values() const

返回包含数据集所有值的列表。

QBarSeries 用于表示条形图数据系列。以下是 QBarSeries 类的一些主要方法和概述:

方法

描述

QBarSeries(QObject *parent = nullptr)

构造函数,创建一个空的 QBarSeries 对象。

void append(QBarSet *set)

将一个 QBarSet 对象添加到系列的末尾。

void append(const QList<QBarSet*> &sets)

将一组 QBarSet 对象添加到系列的末尾。

void replace(int index, QBarSet *set)

替换系列中指定索引位置的 QBarSet 对象。

void replace(const QList<QBarSet*> &sets)

用提供的一组 QBarSet 对象替换整个系列。

void remove(int index)

移除系列中指定索引位置的 QBarSet 对象。

void clear()

清除系列中的所有 QBarSet 对象。

int count() const

返回系列中 QBarSet 对象的数量。

bool isEmpty() const

检查系列是否为空。

QBarSet* at(int index) const

返回系列中指定索引位置的 QBarSet 对象。

QList<QBarSet*> barSets() const

返回包含系列所有 QBarSet 对象的列表。

QBarCategoryAxis 表示条形图横坐标,用于管理和显示条形图中的分类轴,其中每个条形图都属于特定的类别。以下是 QBarCategoryAxis 类的一些主要方法和概述:

方法

描述

QBarCategoryAxis(QObject *parent = nullptr)

构造函数,创建一个空的 QBarCategoryAxis 对象。

void append(const QStringList &categories)

将一组类别添加到轴的末尾。

void append(const QString &category)

将一个类别添加到轴的末尾。

void insert(int index, const QString &category)

在指定索引位置插入一个类别。

void insert(int index, const QStringList &categories)

在指定索引位置插入一组类别。

void remove(const QString &category)

移除指定的类别。

void remove(int index, int count = 1)

从指定索引位置开始移除指定数量的类别。

void clear()

清除轴中的所有类别。

int count() const

返回轴中类别的数量。

QString categoryAt(int index) const

返回轴中指定索引位置的类别。

QStringList categories() const

返回包含轴所有类别的列表。

void setCategories(const QStringList &categories)

设置轴的类别。

void setStartValue(qreal value)

设置轴的起始值。

qreal startValue() const

返回轴的起始值。

void setRange(qreal min, qreal max)

设置轴的范围。

void append(const QVector<QPointF> &points)

将一组点添加到轴的末尾,用于自动设置类别。

void replace(const QVector<QPointF> &points)

用提供的一组点替换整个轴,用于自动设置类别。

如下代码是使用 Qt 的图表模块创建一个包含柱状图和折线图的图表,并显示在 QGraphicsView 控件中,在MainWindow::MainWindow构造函数中我们可以使用如下代码实现柱状图的创建。

图表初始化:创建一个 QChart 对象,并设置图表的标题和动画效果。然后将图表设置给 ui->graphicsView 控件,同时启用抗锯齿渲染。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QChart *chart = new QChart();
chart->setTitle("柱状图统计");
chart->setAnimationOptions(QChart::SeriesAnimations);

// 为graphicsView设置chart
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);

// 构造柱状图
chart =ui->graphicsView->chart();
chart->removeAllSeries();            // 删除所有序列
chart->removeAxis(chart->axisX());   // 删除坐标轴
chart->removeAxis(chart->axisY());   // 删除坐标轴

创建数据集:构造三个 QBarSet 对象,分别表示数学、语文、英语的数据集。同时创建一个 QLineSeries 对象,表示平均分数据集,并设置线条的颜色和宽度。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text());      // 数学字段
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text());   // 语文字段
QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text());    // 英语字段

// 创建折线线条
QLineSeries *Line = new QLineSeries();
Line->setName(theModel->horizontalHeaderItem(4)->text());  // 表示平均分
QPen pen;
pen.setColor(Qt::red);  // 使用红色
pen.setWidth(2);        // 设置宽度
Line->setPen(pen);      // 绘制

添加数据:遍历前10个数据行,将数学、语文、英语的成绩和平均分添加到相应的数据集中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for(int i=0;i< 10;i++)
{
    // 从数据模型获取数据
    setMath->append(theModel->item(i,1)->text().toInt());            // 数学
    setChinese->append(theModel->item(i,2)->text().toInt());         // 语文
    setEnglish->append(theModel->item(i,3)->text().toInt());         // 英语
    Line->append(QPointF(i,theModel->item(i,4)->text().toFloat()));  // 平均分
}

创建柱状图序列:使用 QBarSeries 创建一个柱状图序列,并将三个数据集添加到序列中。同时,将折线图序列也添加到图表中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cppCopy codeQBarSeries *series = new QBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);

chart->addSeries(series);
chart->addSeries(Line);

设置坐标轴:创建横坐标轴 axisX 和纵坐标轴 axisY,设置它们的范围、标签等信息,然后将它们与相应的序列关联。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 创建柱状图序列 QBarSeries 并添加三个数据集
QBarSeries *series = new QBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);

chart->addSeries(series); // 添加柱状图序列
chart->addSeries(Line);   // 添加折线图序列

// 用于横坐标在字符串列表 即UID
QStringList categories;
for (int i=0;i<10;i++)
{
    categories <<theModel->item(i,0)->text();
}

// 柱状图的坐标轴
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append(categories);            // 添加横坐标文字列表
chart->setAxisX(axisX, series);       // 设置横坐标
chart->setAxisX(axisX, Line);         // 设置横坐标

// 设置坐标范围
axisX->setRange(categories.at(0), categories.at(categories.count()-1));

// 数值型坐标作为纵轴
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 100);
axisY->setTitleText("分数");
axisY->setTickCount(6);
axisY->setLabelFormat("%.0f");

图例显示设置:显示图例,并设置图例在底部对齐。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
chart->setAxisY(axisY, series);
chart->setAxisY(axisY, Line);
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);

这样,你就创建了一个包含柱状图和折线图的图表,并将其显示在 QGraphicsView 控件中,运行后则可以得到如下图所示的图例;

1.2 创建饼状图

饼状图(Pie Chart)用于展示各部分占整体的比例关系。它通过在一个圆形区域内绘制扇形来表示数据的相对大小。整个圆表示总体,而每个扇形的弧长(或面积)表示相应类别的数量或比例。

饼状图的主要特点包括:

  1. 占比表示:每个扇形的大小表示相应类别在总体中所占的比例,从而直观地展示各类别之间的相对关系。
  2. 圆形布局:饼状图的数据以圆形的方式呈现,使得用户能够轻松比较各部分的大小。
  3. 清晰易懂:饼状图通常用于表示数据的相对比例,特别适用于展示类别之间的占比关系,非常直观。
  4. 单一变量:饼状图适合展示单一变量的占比关系,不适用于多个变量或时间序列的比较。
  5. 限制数据量:由于饼状图是基于整个圆的,适合表示少量类别的占比关系。当类别过多时,可能导致图形复杂,难以解读。

饼状图常见的应用场景包括市场份额分析、调查结果的占比展示、资源分配比例等。然而,有时候,为了更好地表达数据,也会使用改进版的饼状图,如环形图(Donut Chart)等。

QPieSeries 是 Qt Charts 模块中用于绘制饼状图的数据序列类。它派生自 QAbstractSeries 类,用于管理和展示饼状图中的数据。以下是 QPieSeries 类的一些常用方法和属性,以表格形式概述:

方法

描述

QPieSeries(QObject *parent = nullptr)

构造函数,创建一个 QPieSeries 对象。

~QPieSeries()

析构函数,释放 QPieSeries 对象。

append(QPieSlice *slice)

向饼状图序列中追加一个饼块。

insert(int index, QPieSlice *slice)

在指定位置插入一个饼块。

remove(QPieSlice *slice)

从饼状图序列中移除指定的饼块。

clear()

清除饼状图序列中的所有饼块。

slices()

返回饼状图序列中的所有饼块。

count()

返回饼状图序列中的饼块数量。

at(int index)

返回饼状图序列中指定索引位置的饼块。

setVisible(bool visible)

设置饼状图序列的可见性。

isVisible()

返回饼状图序列的可见性。

setHoleSize(double size)

设置饼状图中间空心的大小,范围为 [0.0, 1.0],0.0 表示没有空心,1.0 表示整个饼状图都是空心。

holeSize()

返回饼状图中间空心的大小。

setPieSize(double size)

设置饼状图的大小,范围为 [0.0, 1.0],默认为 1.0。

pieSize()

返回饼状图的大小。

setLabelsVisible(bool visible)

设置饼块的标签是否可见。

labelsVisible()

返回饼块的标签是否可见。

setLabelsPosition(QPieSlice::LabelPosition position)

设置饼块标签的位置。

labelsPosition()

返回饼块标签的位置。

setLabelsPrecision(int precision)

设置饼块标签显示的小数位数。

labelsPrecision()

返回饼块标签显示的小数位数。

clicked(QPieSlice *slice)

点击饼块时发出的信号,参数为被点击的饼块。

hovered(QPieSlice *slice, bool state)

鼠标悬停在饼块上时发出的信号,参数为被悬停的饼块和悬停状态。

pressed(QPieSlice *slice)

鼠标按下饼块时发出的信号,参数为被按下的饼块。

released(QPieSlice *slice)

鼠标释放饼块时发出的信号,参数为被释放的饼块。

QPieSlice 是 Qt Charts 模块中用于表示饼状图中的单个饼块的类。每个 QPieSlice 对象都代表饼状图中的一个数据分块。

以下是关于 QPieSlice 的一些方法以及说明:

方法

描述

QPieSlice(qreal value, QString label)

构造函数,创建一个带有给定值和标签的 QPieSlice 对象。

~QPieSlice()

析构函数,释放 QPieSlice 对象。

setLabel(QString label)

设置饼块的标签文字。

label()

返回饼块的标签文字。

setValue(qreal value)

设置饼块的值。

value()

返回饼块的值。

setExploded(bool exploded)

设置饼块是否为爆炸状态,即是否与饼图分离。

isExploded()

返回饼块是否为爆炸状态。

setPieSeries(QPieSeries *series)

设置饼块所属的 QPieSeries 对象。

pieSeries()

返回饼块所属的 QPieSeries 对象。

setBrush(const QBrush &brush)

设置饼块的画刷,即填充颜色。

brush()

返回饼块的画刷。

setLabelBrush(const QBrush &brush)

设置饼块标签的画刷,即标签的颜色。

labelBrush()

返回饼块标签的画刷。

setPen(const QPen &pen)

设置饼块的画笔,即边框颜色和样式。

pen()

返回饼块的画笔。

setLabelVisible(bool visible)

设置饼块标签是否可见。

isLabelVisible()

返回饼块标签是否可见。

setExplodeDistanceFactor(qreal factor)

设置饼块爆炸时的距离因子,即与饼图分离的距离。

explodeDistanceFactor()

返回饼块爆炸时的距离因子。

setPercentage(qreal percentage)

设置饼块的百分比值。

percentage()

返回饼块的百分比值。

clicked(bool state)

鼠标点击饼块时发出的信号,参数为鼠标点击的状态(按下或释放)。

hovered(bool state)

鼠标悬停在饼块上时发出的信号,参数为悬停状态。

pressed()

鼠标按下饼块时发出的信号。

released()

鼠标释放饼块时发出的信号。

QPieSlice 主要用于配置和管理饼状图中的单个数据分块,包括设置饼块的标签、值、颜色、样式等属性。

饼状图的绘制流程与柱状图一样,主要以下几个步骤:

饼图初始化: 创建一个QChart对象,并设置其动画选项。然后将该图表对象设置为QGraphicsView的图表,并启用反锯齿渲染。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 饼图初始化
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);

// 绘制饼图
chart->removeAllSeries();

创建饼图序列:为图表创建一个新的饼图序列(QPieSeries),并通过循环的方式向序列中添加成绩。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 创建饼图序列
QPieSeries *series = new QPieSeries();

// 饼图中间空心的大小
series->setHoleSize(0.30);

// 添加分块数据
for (int i=0;i<=4;i++)
{
    // 获得QTreeWidgetItem的item
    QTreeWidgetItem* item=ui->treeWidget->topLevelItem(i);

    // 获取分析对象,数学、英语、语文或平均分,添加一个饼图分块数据,标签,数值
    series->append(item->text(0),item->text(1).toFloat());
}

添加分块数据到饼图:QTreeWidget中获取每个分析对象(数学、英语、语文或平均分),并将其添加到饼图序列中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 饼图分块
QPieSlice *slice;

// 设置每个分块的标签文字
for(int i=0;i<=4;i++)
{
    // 获取分块
    slice =series->slices().at(i);

    // 设置分块的标签
    slice->setLabel(slice->label()+QString::asprintf(": %.0f人, %.1f%%", slice->value(),slice->percentage()*100));

    // 信号与槽函数关联,鼠标落在某个分块上时,此分块弹出
    connect(slice, SIGNAL(hovered(bool)),this, SLOT(on_PieSliceHighlight(bool)));
}

slice->setExploded(true);           // 最后一个设置为exploded
series->setLabelsVisible(true);     // 只影响当前的slices,必须添加完slice之后再设置
chart->addSeries(series);           // 添加饼图序列

chart->legend()->setVisible(true);  // 图例
chart->legend()->setAlignment(Qt::AlignRight);

设置饼图分块的标签和槽函数关联: 对于每个分块,设置其标签文字,包括数值和百分比,并关联鼠标悬停事件的槽函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 鼠标移入移出时触发hovered信号
void MainWindow::on_PieSliceHighlight(bool show)
{
    QPieSlice *slice;
    slice=(QPieSlice *)sender();

    // 动态设置setExploded效果
    // slice->setLabelVisible(show);
    slice->setExploded(show);
}

上述代码流程实现了在Qt中使用QPieSeriesQPieSlice绘制饼状图的功能,包括图表的初始化、数据的设置、分块标签的添加、饼图分块的突出显示等。在图表中,每个分块代表一种分析对象,标签包含人数和百分比信息,运行后输出如下效果;

1.3 创建堆叠图

堆叠图(Stacked Chart)用于展示多个数据系列的累积效果,即将不同系列的数据在同一数值点上进行堆叠显示。这种图表形式旨在突出整体的趋势以及各组成部分的相对贡献。

堆叠图有多种形式,其中两种常见的类型包括:

  1. 堆叠柱状图(Stacked Bar Chart):在同一类别或数值点上,将不同系列的柱状图堆叠在一起。每个柱状图的高度表示该系列在该点上的数值,而整个柱状图的高度表示各个系列在该点上的累积总和。
  2. 堆叠面积图(Stacked Area Chart):在同一类别或数值点上,将不同系列的面积图堆叠在一起。每个面积图的面积表示该系列在该点上的数值,而整个堆叠面积图的高度表示各个系列在该点上的累积总和。

堆叠图的优势在于能够直观地显示各部分在整体中的相对比例,并清晰地展示随时间或其他维度的变化。这种图表类型通常用于比较多个系列的总体趋势,并强调各个系列之间的相对贡献。在堆叠图中,每个系列的数值贡献会在相同的数值点上叠加显示,使得读者能够更容易比较各系列的相对大小。

堆叠图的创建需要用到QStackedBarSeriesQBarCategoryAxis类,QStackedBarSeries 是 Qt Charts 模块中用于创建堆叠柱状图的类。堆叠柱状图显示多个柱状系列的堆叠效果,每个柱状系列由一个或多个柱状条组成,这些柱状条按照数据堆叠在一起,形成整体的柱状图。

以下是 QStackedBarSeries 的一些重要方法和属性:

方法

描述

QStackedBarSeries(QObject *parent = nullptr)

构造函数,创建一个 QStackedBarSeries 对象。

void append(QBarSet *set)

将一个 QBarSet 添加到序列中。

void append(QList<QBarSet *> sets)

将一组 QBarSet 添加到序列中。

QList<QBarSet *> barSets() const

返回序列中的所有 QBarSet。

void setLabelsVisible(bool visible)

设置是否显示柱状图的标签。

bool labelsVisible() const

返回柱状图的标签可见性。

void setLabelsFormat(const QString &format)

设置标签的显示格式。

QString labelsFormat() const

返回标签的显示格式。

void setLabelsPosition(QAbstractBarSeries::LabelsPosition position)

设置标签的位置。

QAbstractBarSeries::LabelsPosition labelsPosition() const

返回标签的位置。

QStackedBarSeries 通过添加不同的 QBarSet 对象来创建堆叠效果。每个 QBarSet 对象代表一个柱状系列,它包含了一组柱状条的数据。标签、颜色和其他样式属性可以通过 QBarSet 进行定制。使用这些方法和属性,可以方便地控制堆叠柱状图的外观和行为,如下代码则是堆叠图创建的实现;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 初始化叠加柱状图绘制窗口
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);

// 绘制叠加柱状图
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());

// 创建三门课程的数据集
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text());
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text());
QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text());

// 添加前十个分数数据到数据集
for(int i=0;i<20;i++)
{
    setMath->append(theModel->item(i,1)->text().toInt());
    setChinese->append(theModel->item(i,2)->text().toInt());
    setEnglish->append(theModel->item(i,3)->text().toInt());
}

// 创建QStackedBarSeries对象并添加数据集
QStackedBarSeries *series = new QStackedBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
series->setLabelsVisible(true);

// 添加序列到图表
chart->addSeries(series);

QStringList categories;

// 绘制前十个数据
for (int i=0;i<10;i++)
{
    categories <<theModel->item(i,0)->text();
}

// 类别坐标轴 作为横轴
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append(categories);
chart->setAxisX(axisX, series);
axisX->setRange(categories.at(0), categories.at(categories.count()-1));

// 数值坐标轴 作为纵轴
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 300);
axisY->setTitleText("总分");
axisY->setTickCount(6);
axisY->setLabelFormat("%.0f");
chart->setAxisY(axisY, series);

// 设置图表属性
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);

运行后,通过QBarSet保存课程数据集,最后增加横轴纵轴区间,当数据被加载后,图表则会输出如下所示的数据集;

1.4 创建百分比图

百分比图(Percentage Chart)用于显示各部分占整体的百分比关系的图表。这种图表通过以百分比形式展示每个部分在总体中所占比例,提供了一种直观的方式来比较不同部分的相对大小。

百分比图有多种形式,其中一些常见的类型包括:

  1. 百分比柱状图(Percentage Bar Chart):类似于常规柱状图,但每个柱的高度表示相对于整体的百分比。
  2. 百分比堆叠柱状图(Percentage Stacked Bar Chart):将柱叠加在一起,每个部分的高度表示相对于总体的百分比。
  3. 百分比饼状图(Percentage Pie Chart):类似于饼状图,但每个扇形的角度或面积表示相对于整体的百分比。
  4. 百分比面积图(Percentage Area Chart):面积图的每个区域表示相对于整体的百分比。
  5. 百分比堆叠面积图(Percentage Stacked Area Chart):将面积叠加在一起,每个区域的面积表示相对于总体的百分比。

这些图表形式在不同情境下用于展示数据的占比关系,特别适用于需要强调相对比例的场景。百分比图通常能够帮助观众更容易地理解各部分在整体中的贡献,是一种有力的数据可视化工具。

使用百分比图时,注意确保数据的总和为100%。百分比图在市场份额分析、调查结果的占比展示、资源分配比例等方面得到广泛应用。

QPercentBarSeries 是 Qt Charts 模块中用于绘制百分比柱状图的类。它派生自 QAbstractBarSeries 类,表示一个二维坐标系中的数据系列,其中的数据以百分比柱状图的形式呈现。

以下是关于 QPercentBarSeries 的一些方法以及说明:

方法

描述

QPercentBarSeries()

构造函数,创建一个 QPercentBarSeries 对象。

~QPercentBarSeries()

析构函数,释放 QPercentBarSeries 对象。

setLabelsVisible(bool)

设置百分比柱状图上的数据标签是否可见。

labelsVisible()

返回百分比柱状图上的数据标签是否可见的状态。

setLabelsPosition(Position)

设置百分比柱状图上的数据标签位置,Position 是一个枚举类型,表示标签的位置,如上方、下方、内部等。

labelsPosition()

返回百分比柱状图上的数据标签位置。

setLabelsFormat(QString)

设置百分比柱状图上的数据标签的格式,使用字符串指定标签的显示格式。

labelsFormat()

返回百分比柱状图上的数据标签的显示格式。

setPercentageVisible(bool)

设置百分比柱状图上的百分比标签是否可见。

percentageVisible()

返回百分比柱状图上的百分比标签是否可见的状态。

setStackingGap(qreal)

设置百分比柱状图中堆叠的百分比柱之间的间隙。

stackingGap()

返回百分比柱状图中堆叠的百分比柱之间的间隙。

append(QBarSet*)

在百分比柱状图中追加一个数据集。

insert(int, QBarSet*)

在百分比柱状图中插入一个数据集,参数为位置索引和 QBarSet 对象。

remove(QBarSet*)

从百分比柱状图中移除指定的数据集。

take(int)

从百分比柱状图中移除并返回指定位置的数据集。

take(QBarSet*)

从百分比柱状图中移除指定的数据集并返回。

count()

返回百分比柱状图中数据集的数量。

barSets()

返回百分比柱状图中所有数据集的列表。

barWidth()

返回百分比柱状图中百分比柱的宽度。

barWidthChanged(qreal)

当百分比柱状图中百分比柱的宽度发生变化时发出的信号,参数为新的宽度值。

QPercentBarSeries 类主要用于在图表中绘制百分比柱状图,其中的数据集可以包含多个柱子,每个柱子表示一个百分比。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 百分比柱状图初始化
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);

// 绘制百分比柱状图
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());

// 创建数据集
QBarSet *setMath = new QBarSet(theModel->horizontalHeaderItem(1)->text());
QBarSet *setChinese = new QBarSet(theModel->horizontalHeaderItem(2)->text());
QBarSet *setEnglish= new QBarSet(theModel->horizontalHeaderItem(3)->text());

QTreeWidgetItem *item;
QStringList categories;

for (int i=0;i<=4;i++)
{
    // 从分数段统计数据表里获取数据添加到数据集
    item=ui->treeWidget->topLevelItem(i);

    // 横坐标的标签
    categories<<item->text(0);

    // 添加数据到QBarSet中
    setMath->append(item->text(1).toFloat());
    setChinese->append(item->text(2).toFloat());
    setEnglish->append(item->text(3).toFloat());
}

// 添加序列
QPercentBarSeries *series = new QPercentBarSeries();
series->append(setMath);
series->append(setChinese);
series->append(setEnglish);
series->setLabelsVisible(true);
series->setLabelsFormat("@value人");
chart->addSeries(series);

// 添加横坐标
QBarCategoryAxis *axisX = new QBarCategoryAxis();
axisX->append(categories);
chart->setAxisX(axisX, series);
axisX->setRange(categories.at(0), categories.at(categories.count()-1));

// 添加纵坐标
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 100);
axisY->setTitleText("百分比");
axisY->setTickCount(6);
axisY->setLabelFormat("%.1f");
chart->setAxisY(axisY, series);

// 设置属性
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);

运行后则可输出不同分数段每一门成绩的百分比分布情况,如下图所示;

1.5 创建散点图

散点图(Scatter Plot)是一种二维图表,用于显示两个变量之间的关系。散点图的每个数据点由两个数值组成,分别对应于图表的横轴和纵轴。通过在图表中绘制这些点,可以观察和分析变量之间的关联性、趋势、聚集程度等。

散点图的特点包括:

  1. 数据点表示:每个数据点在图表上表示为一个独立的点,其中横轴对应一个变量,纵轴对应另一个变量。
  2. 关系展示:散点图主要用于展示两个变量之间的关系,例如相关性、分布情况、趋势等。
  3. 离散数据:适用于离散型数据,每个点表示一个具体的观测值。
  4. 聚类发现:通过观察数据点的分布,可以发现数据是否呈现出某种聚类模式。
  5. 异常值检测:可以用于检测异常值,即图表中偏离正常分布的离群点。

散点图的应用场景非常广泛,常见的用途包括:

  • 相关性分析:通过观察散点图,可以初步了解两个变量之间的相关性,是进行相关性分析的一种可视化手段。
  • 趋势分析:散点图可以用于观察两个变量之间是否存在趋势,是进行趋势分析的有力工具。
  • 异常值检测:通过识别离群点,可以发现数据中的异常值,有助于数据清理和分析的准确性。
  • 聚类分析:观察数据点的分布,可以发现是否存在某种聚类模式,对于数据的分组有一定帮助。

总体而言,散点图是一种简单而强大的工具,可用于初步探索和理解两个变量之间的关系。

QSplineSeries 是 Qt Charts 模块中用于绘制光滑曲线的类。它表示图表中的一条曲线,通过一系列的数据点来定义曲线的形状。

以下是关于 QSplineSeries 的一些方法以及说明:

方法

描述

QSplineSeries(QObject *parent = nullptr)

构造函数,创建一个 QSplineSeries 对象。

~QSplineSeries()

析构函数,释放 QSplineSeries 对象。

append(QPointF point)

向曲线中追加一个数据点。

append(QList<QPointF> points)

向曲线中追加一组数据点。

replace(int index, QPointF point)

替换指定索引处的数据点。

replace(QList<QPointF> points)

替换曲线中的所有数据点。

remove(int index)

移除指定索引处的数据点。

remove(int index, int count)

移除从指定索引开始的指定数量的数据点。

clear()

清空曲线中的所有数据点。

pointsVector()

返回曲线的数据点。

setUseOpenGL(bool enable)

设置是否使用 OpenGL 进行绘制。

useOpenGL()

返回是否使用 OpenGL 进行绘制。

setPen(const QPen &pen)

设置曲线的画笔,即曲线的颜色和样式。

pen()

返回曲线的画笔。

setBrush(const QBrush &brush)

设置曲线的画刷,即填充颜色。

brush()

返回曲线的画刷。

setPointLabelsVisible(bool visible)

设置是否显示数据点的标签。

isPointLabelsVisible()

返回数据点的标签是否可见。

setPointLabelsFormat(const QString &format)

设置数据点标签的显示格式,支持使用占位符。

pointLabelsFormat()

返回数据点标签的显示格式。

setPointLabelsColor(const QColor &color)

设置数据点标签的颜色。

pointLabelsColor()

返回数据点标签的颜色。

setPointLabelsFont(const QFont &font)

设置数据点标签的字体。

pointLabelsFont()

返回数据点标签的字体。

setPointsVisible(bool visible)

设置是否显示数据点。

arePointsVisible()

返回数据点是否可见。

setPointLabelsClipping(bool clipping)

设置是否裁剪超出绘图区域的数据点标签。

isPointLabelsClipping()

返回数据点标签是否裁剪超出绘图区域。

clicked(QPointF point)

鼠标点击曲线时发出的信号,参数为鼠标点击的数据点坐标。

hovered(QPointF point, bool state)

鼠标悬停在曲线上时发出的信号,参数为悬停状态以及悬停位置的数据点坐标。

pressed(QPointF point)

鼠标按下曲线时发出的信号,参数为鼠标按下的数据点坐标。

released(QPointF point)

鼠标释放曲线时发出的信号,参数为鼠标释放的数据点坐标。

doubleClicked(QPointF point)

鼠标双击曲线时发出的信号,参数为鼠标双击的数据点坐标。

QSplineSeries 主要用于绘制光滑曲线,通过添加一系列的数据点,可以在图表中呈现出相应的曲线形状。

QScatterSeries 是 Qt Charts 模块中用于绘制散点图的类。它派生自 QXYSeries 类,用于表示图表中的一组散点数据,通过一系列的坐标点来显示离散的数据分布。

以下是关于 QScatterSeries 的一些方法以及说明:

方法

说明

QScatterSeries(QObject *parent = nullptr)

构造函数,创建一个 QScatterSeries 对象。

~QScatterSeries()

析构函数,释放 QScatterSeries 对象。

append(QPointF point)

向散点图中追加一个数据点。

append(QList<QPointF> points)

向散点图中追加一组数据点。

replace(int index, QPointF point)

替换指定索引处的数据点。

replace(QList<QPointF> points)

替换散点图中的所有数据点。

remove(int index)

移除指定索引处的数据点。

remove(int index, int count)

移除从指定索引开始的指定数量的数据点。

clear()

清空散点图中的所有数据点。

pointsVector()

返回散点图的数据点。

setMarkerShape(QScatterSeries::MarkerShape shape)

设置散点的形状,可以是圆形、方形等。

markerShape()

返回散点的形状。

setMarkerSize(qreal size)

设置散点的大小。

markerSize()

返回散点的大小。

setPen(const QPen &pen)

设置散点图的画笔,即散点的边框颜色和样式。

pen()

返回散点图的画笔。

setBrush(const QBrush &brush)

设置散点图的画刷,即散点的填充颜色。

brush()

返回散点图的画刷。

setBorderColor(const QColor &color)

设置散点的边框颜色。

borderColor()

返回散点的边框颜色。

setBackgroundColor(const QColor &color)

设置散点的背景颜色。

backgroundColor()

返回散点的背景颜色。

setBorderColor(const QColor &color)

设置散点的边框颜色。

borderColor()

返回散点的边框颜色。

setBrush(const QBrush &brush)

设置散点的画刷,即填充颜色。

brush()

返回散点的画刷。

setPen(const QPen &pen)

设置散点的画笔,即边框颜色和样式。

pen()

返回散点的画笔。

setUseOpenGL(bool enable)

设置是否使用 OpenGL 进行绘制。

useOpenGL()

返回是否使用 OpenGL 进行绘制。

setMarkerShape(QScatterSeries::MarkerShape shape)

设置散点的形状,可以是圆形、方形等。

markerShape()

返回散点的形状。

setMarkerSize(qreal size)

设置散点的大小。

markerSize()

返回散点的大小。

setMarkerColor(const QColor &color)

设置散点的颜色。

markerColor()

返回散点的颜色。

clicked(QPointF point)

鼠标点击散点时发出的信号,参数为鼠标点击的数据点坐标。

hovered(QPointF point, bool state)

鼠标悬停在散点上时发出的信

绘制散点图实现代码如下所示;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 散点图初始化
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::SeriesAnimations);
ui->graphicsView->setChart(chart);
ui->graphicsView->setRenderHint(QPainter::Antialiasing);

// 清空绘图区
chart->removeAllSeries();
chart->removeAxis(chart->axisX());
chart->removeAxis(chart->axisY());

// 光滑曲线序列
QSplineSeries *seriesLine = new QSplineSeries();
seriesLine->setName("曲线");
QPen pen;
pen.setColor(Qt::blue);
pen.setWidth(2);
seriesLine->setColor(Qt::blue);
seriesLine->setPen(pen);

// 散点序列
QScatterSeries *series0 = new QScatterSeries();
series0->setName("散点");
series0->setMarkerShape(QScatterSeries::MarkerShapeCircle);
series0->setBorderColor(Qt::black);
series0->setBrush(QBrush(Qt::red));
series0->setMarkerSize(12);

// 随机数种子
qsrand(QTime::currentTime().second());

// 设置曲线随机数
for (int i=0;i<10;i++)
{
    int x=(qrand() % 20);    // 0到20之间的随机数
    int y=(qrand() % 20);
    series0->append(x,y);    // 散点序列
    seriesLine->append(x,y); // 光滑曲线序列
}

chart->addSeries(series0);
chart->addSeries(seriesLine);

// 增加Y坐标轴(可注释)
QValueAxis *axisY = new QValueAxis;
axisY->setRange(0, 20);
axisY->setTitleText("Y坐标");
axisY->setTickCount(11);
axisY->setLabelFormat("%.0f");
axisY->setGridLineVisible(true);
chart->setAxisY(axisY, series0);
chart->setAxisY(axisY, seriesLine);

// 增加X坐标轴(可注释)
QValueAxis *axisX = new QValueAxis;
axisX->setRange(0, 20);
axisX->setTitleText("X");
axisX->setTickCount(11);
axisX->setLabelFormat("%.0f");
axisX->setGridLineVisible(true);
chart->setAxisX(axisX, series0);
chart->setAxisX(axisX, seriesLine);

// 创建缺省的坐标轴(默认缺省值)
chart->createDefaultAxes();
chart->axisX()->setTitleText("X 轴");
chart->axisX()->setRange(-2,22);

chart->axisY()->setTitleText("Y 轴");
chart->axisY()->setRange(-2,22);

chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignRight);

// 绑定槽函数,用于点击图例显示与隐藏数据
foreach (QLegendMarker* marker, chart->legend()->markers())
{
    QObject::disconnect(marker, SIGNAL(clicked()), this, SLOT(on_chartBarLegendMarkerClicked()));
    QObject::connect(marker, SIGNAL(clicked()), this, SLOT(on_chartBarLegendMarkerClicked()));
}

运行上述代码则可实现输出随机散点图,其中右侧散点与曲线可以进行自定义隐藏与显示,如下图所示;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Qt | QChart和QChartView配合实现面积图、条形图、折线图、饼图、曲线图、散点图,支持显示坐标值和坐标点。
一般我将ctrl+alt+L或者shift+alt+L来展开和折叠所有代码块,方便快速定位函数位置。(这个需要自定义)
Qt历险记
2024/07/03
2.3K0
Qt | QChart和QChartView配合实现面积图、条形图、折线图、饼图、曲线图、散点图,支持显示坐标值和坐标点。
C++ Qt开发:Charts绘图组件概述
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QCharts二维绘图组件的常用方法及灵活运用。
王 瑞
2023/12/23
2.6K0
C++ Qt开发:Charts绘图组件概述
C/C++ Qt QChart 绘图组件应用
QtCharts 组件是QT中提供图表绘制的模块,该模块可以方便的绘制常规图形,Qtcharts 组件基于GraphicsView模式实现,其核心是QChartView和QChart的二次封装版。
王 瑞
2022/12/23
1.1K0
C/C++ Qt QChart 绘图组件应用
Qt | QChart+QChartView+QLineSeries(折线图)+QBarSeries(柱状图)实战
QLineSeries 是 Qt 中的一个类,用于在图表中表示一系列的数据点。它继承自 QAbstractSeries 类,提供了绘制折线图所需的基本功能。
Qt历险记
2024/07/30
2.4K0
Qt | QChart+QChartView+QLineSeries(折线图)+QBarSeries(柱状图)实战
Qt | QStackedBarSeries(堆叠条形图)+QPercentBarSeries(堆叠百分比条形图)
5. 确保QStackedBarSeries类能够与其他图表元素协同工作,以便在图表中显示堆叠条形图。
Qt历险记
2024/08/05
5200
Qt | QStackedBarSeries(堆叠条形图)+QPercentBarSeries(堆叠百分比条形图)
52.Qt-Charts动态显示多条折线电压值(实现示波器效果)
Qt 5.7过后Qt添加了官方的Chart库,之前就用的比较习惯,这次把源码发出来,给入门的同学们参考参考.
诺谦
2020/01/15
2.3K0
52.Qt-Charts动态显示多条折线电压值(实现示波器效果)
QT charts 动态刷新曲线图
用vs+QT开发应用程序时,当需要显示图表时,使用QtCharts是不错的选择。QtCharts是Qt提供的图表模块,在Qt5.7以前只有商业版才有QtCharts,但是从5.7开始,社区版也包含了QtCharts。QtCharts可以很方便地绘制常见的折线图、柱状图、饼图等图表。
zls365
2020/12/15
6.4K0
Qt | QPieSeries(饼图)+QSplineSeries(曲线图)+QAreaSeries(面积图)实战
QPieSeries是一个用于创建和展示饼图的类。它提供了基本的饼图绘制功能,包括设置饼图的标签、数据和样式。用户可以通过实例化QPieSeries类并调用其方法来生成饼图。此外,QPieSeries还支持一些交互功能,如设置饼图的颜色、边框宽度等。
Qt历险记
2024/07/31
6300
Qt | QPieSeries(饼图)+QSplineSeries(曲线图)+QAreaSeries(面积图)实战
C++ Qt开发:Charts折线图绘制详解
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QCharts折线图的常用方法及灵活运用。
王 瑞
2023/12/24
3.9K0
C++ Qt开发:Charts折线图绘制详解
Qt官方示例-图表主题
示例可以设置图表的系统内置主题。 0x00 主题样式预览 Light主题 Blue Cerulean主题 Dark主题 Brow Sand主题 Blue NCS主题 High ontrast主题 B
Qt君
2019/10/23
1.1K0
Qt官方示例-图表主题
VS2017中使用QT Chart图表
有关QtChart的介绍在这就不详谈了,想要具体了解的百度就可以,官网和网站大多数都是介绍如何在QtCreator中使用QtChart,而本文主要介绍如何在vs中使用。
zls365
2020/09/28
2.7K0
VS2017中使用QT Chart图表
C++ Qt开发:Charts与数据库组件联动
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍Charts组件与QSql数据库组件的常用方法及灵活运用。
王 瑞
2024/01/06
4990
C++ Qt开发:Charts与数据库组件联动
47.QT-QChart之曲线图,饼状图,条形图使用
1.使用准备 在pro中, 添加QT+= charts 然后在界面头文件中添加头文件并声明命名空间,添加: #include <QtCharts> QT_CHARTS_USE_NAMESPACE 2.QChart之曲线图 绘制曲线图需要用到3个类 QSplineSeries: 用于创建有由一系列数据组成的曲线.类似的还有QPieSeries(饼图数据). QLineSeries(折线数据) QChart: 图表界面,用来管理图表内容,颜色,大小等 QChartView: 负责显示QChart 效
诺谦
2019/06/14
3.4K0
Qt官方示例-嵌套甜甜圈
  先创建一个QChartView实例并启用抗锯齿。然后从QChartView实例获得一个QChart对象。
Qt君
2020/05/08
1.6K0
Qt官方示例-嵌套甜甜圈
C# 实时折线图,波形图
此Demo是采用VS自带的Chart图表控件,制作实时动态显示的折线图,和波形图。本文仅供学习分享使用,如有不足之处,还请指正。
zls365
2020/08/19
4.5K1
C# 实时折线图,波形图
Qt 2D数据可视化之QCharts
Qt Charts 在Qt4时代就有了,不过一直以来是商业许可的。QCharts可以在社区版使用后,Qt画图再也不用需要配置第三方的qcustomplot和qwt插件了,QCharts功能比两者都好,且易用安装和使用。从5.7.0开始,Qt Charts 也纳入了开放许可证。
用户5908113
2019/12/19
1.6K0
C/C++ Qt 数据库与Chart实现历史数据展示
在前面的博文中具体介绍了QChart组件是如何绘制各种通用的二维图形的,本章内容将继续延申一个新的知识点,通过数据库存储某一段时间节点数据的走向,当用户通过编辑框提交查询记录时,程序自动过滤出该时间节点下所有的数据,并将该数据动态绘制到图形组件内,实现动态查询图形的功能。
王 瑞
2022/12/22
5300
C/C++ Qt 数据库与Chart实现历史数据展示
C++曲线图折线图QT窗体绘图excel数据导入
如需安装运行环境或远程调试,可加QQ905733049, 或QQ2945218359由专业技术人员远程协助!
用户9804507
2022/06/06
1.3K0
C++曲线图折线图QT窗体绘图excel数据导入
PyQt5可视化 7 饼图和柱状图实操案例 ④层叠柱状图和百分比柱状图及饼图的实现【超详解图文教程】
目录 一、层叠柱状图 1 初始化层叠柱状图和绘制层叠柱状图函数 2 构造函数里调用  3 draw_stackedBar函数 4 运行效果  5 层叠柱状图相关函数源码  二、百分比柱状图 1 初始化百分比柱状图和绘制百分比柱状图函数 2 构造函数里调用  3 draw_percentBar函数 4 运行效果 2.4.1 统帅的统计结果 2.4.2 百分比柱状图效果图  5 百分比柱状图相关函数源码 三、饼图 1 初始化饼图函数 2 构造函数中调用  3 饼图的窗体界面  4 drawPieChart函数 
会洗碗的CV工程师
2023/03/16
1.3K0
PyQt5可视化 7 饼图和柱状图实操案例 ④层叠柱状图和百分比柱状图及饼图的实现【超详解图文教程】
Qt | QChartView+QDateTimeAxis(日期和时间数据图表)+QPieSeries(饼图)
QDateTimeAxis 是 Qt 中用于图表的轴类,它专门用于处理日期和时间数据。这个类允许你在图表上显示和解释与日期和时间相关的数据点。例如,在 Qt 的图表库中,你可以使用 QDateTimeAxis 来创建一个时间序列图表,展示股票价格、天气数据或其他随时间变化的数据。
Qt历险记
2024/08/02
7200
Qt | QChartView+QDateTimeAxis(日期和时间数据图表)+QPieSeries(饼图)
推荐阅读
相关推荐
Qt | QChart和QChartView配合实现面积图、条形图、折线图、饼图、曲线图、散点图,支持显示坐标值和坐标点。
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档