Графики в Qt через QCustomPlot
В статье показывается пример установки и демонстрации возможностей библиотеки QCustomPlot для рисования графиков на QtWidgets.
Update 2018. В бесплатной версии Qt появились Qt Charts, но они распространяются по GPL лицензии. А это накладывает очень серьезные ограничения для распространения ваших программ. Поэтому для нормального использования Qt Charts нужно брать платную версию Qt.
Поэтому приветствуются альтернативы, которой и является QCustomPlot.
Где найти
Идем на сайт https://www.qcustomplot.com:
И скачиваем библиотеку из соответствующего раздела:
Из всей библиотеки нам потребуется только два файла: qcustomplot.cpp
и qcustomplot.h
:
Подключение библиотеки
Создадим для примера приложение Qt Widgets:
В папку с исходными кодами проекта скинем наши два файла библиотеки. Обратите на этот шаг внимание! Многие данный шаг, как показывает практика, пропускают, и загружают потом в проект эти файлы из распакованного архива, а не из папки своего проекта:
Щелкнем правой кнопкой по проекту в Qt Creator и выберем добавление существующих файлов Add Existing Files…
:
Выберем два наших файла библиотеки:
Они добавятся к нашему проекту:
Перейдем в файл проекта .pro
и допишем там слово printsupport
:
Перейдем на форму:
Разместим там кнопку и Widget
:
Щелкнем по Widget
правой кнопкой и перейдем к Promote to…
:
Там пропишем класс графиков QCustomPlot
и нажмем на Add…
:
А потом на Promote
:
Внешне ничего не изменилось, но, если мы запустим приложение, то увидим координатную сетку:
Иногда после данных действий кнопка запуска неактивна и серая вместо того, чтобы быть зеленой. Данный глюк, можно, например, быстро решить, переключить режим компилирования с Debug на Release (или наоборот), а потом обратно переключить:
Теперь нарисуем какой-нибудь график. Нам потребуется имя компонента Widget, чтобы обращаться к нему:
Перейдем к коду кнопки при клике:
И напишем, например, такой код:
//Рисуем график y=x*x
//Сгенерируем данные
//Для этого создадим два массива точек:
//один для сохранения x координат точек,
//а второй для y соответственно
double a = -1; //Начало интервала, где рисуем график по оси Ox
double b = 1; //Конец интервала, где рисуем график по оси Ox
double h = 0.01; //Шаг, с которым будем пробегать по оси Ox
int N = (b - a) / h + 2; //Вычисляем количество точек, которые будем отрисовывать
QVector<double> x(N), y(N); //Массивы координат точек
//Вычисляем наши данные
int i=0;
//Пробегаем по всем точкам
for (double X = a; X <= b; X += h) {
x[i] = X;
y[i] = X * X;//Формула нашей функции
i++;
}
ui->widget->clearGraphs();//Если нужно, но очищаем все графики
//Добавляем один график в widget
ui->widget->addGraph();
//Говорим, что отрисовать нужно график по нашим двум массивам x и y
ui->widget->graph(0)->setData(x, y);
//Подписываем оси Ox и Oy
ui->widget->xAxis->setLabel("x");
ui->widget->yAxis->setLabel("y");
//Установим область, которая будет показываться на графике
ui->widget->xAxis->setRange(a, b);//Для оси Ox
//Для показа границ по оси Oy сложнее, так как надо по правильному
//вычислить минимальное и максимальное значение в векторах
double minY = y[0], maxY = y[0];
for (int i = 1; i < N; i++) {
if (y[i] < minY) minY = y[i];
if (y[i] > maxY) maxY = y[i];
}
ui->widget->yAxis->setRange(minY, maxY);//Для оси Oy
//И перерисуем график на нашем widget
ui->widget->replot();
При запуске приложение и нажатии на кнопку получим вот это:
Вот и всё. Много примеров ещё в архиве с данной библиотекой, что вы скачивали, и на сайте ее тоже много. Так что дерзайте!
График в виде точек
Чтобы график рисовался не линией, а точками, достаточно прописать это в свойствах графика. Ниже представлен пример такого графика:
ui->widget->graph(0)->setPen(QColor(50, 50, 50, 255));//задаем цвет точки
ui->widget->graph(0)->setLineStyle(QCPGraph::lsNone);//убираем линии
//формируем вид точек
ui->widget->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 4));
Полный код:
//Рисуем график точками y=x*x
//Сгенерируем данные
//Для этого создадим два массива точек:
//один для сохранения x координат точек,
//а второй для y соответственно
double a = -1; //Начало интервала, где рисуем график по оси Ox
double b = 1; //Конец интервала, где рисуем график по оси Ox
double h = 0.1; //Шаг, с которым будем пробегать по оси Ox
int N = (b - a) / h + 2; //Вычисляем количество точек, которые будем отрисовывать
QVector<double> x(N), y(N); //Массивы координат точек
//Вычисляем наши данные
int i=0;
//Пробегаем по всем точкам
for (double X = a; X <= b; X += h) {
x[i] = X;
y[i] = X * X;//Формула нашей функции
i++;
}
ui->widget->clearGraphs();//Если нужно, но очищаем все графики
//Добавляем один график в widget
ui->widget->addGraph();
//Говорим, что отрисовать нужно график по нашим двум массивам x и y
ui->widget->graph(0)->setData(x, y);
ui->widget->graph(0)->setPen(QColor(50, 50, 50, 255));//задаем цвет точки
ui->widget->graph(0)->setLineStyle(QCPGraph::lsNone);//убираем линии
//формируем вид точек
ui->widget->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 4));
//Подписываем оси Ox и Oy
ui->widget->xAxis->setLabel("x");
ui->widget->yAxis->setLabel("y");
//Установим область, которая будет показываться на графике
ui->widget->xAxis->setRange(a, b);//Для оси Ox
//Для показа границ по оси Oy сложнее, так как надо по правильному
//вычислить минимальное и максимальное значение в векторах
double minY = y[0], maxY = y[0];
for (int i = 1; i < N; i++) {
if (y[i] < minY) minY = y[i];
if (y[i] > maxY) maxY = y[i];
}
ui->widget->yAxis->setRange(minY, maxY);//Для оси Oy
//И перерисуем график на нашем widget
ui->widget->replot();
График массива точек
Ниже рассмотрен более простой пример, где отображается график в виде точек из набора точек, заданных вручную:
//Рисуем точки
int N = 5; //Допустим, что у нас пять точек
QVector<double> x(N), y(N); //Массивы координат точек
//Зададим наши точки
x[0] = 1.0; y[0] = 2.0;
x[1] = 4.0; y[1] = 1.0;
x[2] = 3.0; y[2] = 0.0;
x[3] = 0.5; y[3] = 2.2;
x[4] = 1.5; y[4] = 0.7;
ui->widget->clearGraphs();//Если нужно, но очищаем все графики
//Добавляем один график в widget
ui->widget->addGraph();
//Говорим, что отрисовать нужно график по нашим двум массивам x и y
ui->widget->graph(0)->setData(x, y);
ui->widget->graph(0)->setPen(QColor(50, 50, 50, 255));//задаем цвет точки
ui->widget->graph(0)->setLineStyle(QCPGraph::lsNone);//убираем линии
//формируем вид точек
ui->widget->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 4));
//Подписываем оси Ox и Oy
ui->widget->xAxis->setLabel("x");
ui->widget->yAxis->setLabel("y");
//Установим область, которая будет показываться на графике
ui->widget->xAxis->setRange(-1, 5);//Для оси Ox
ui->widget->yAxis->setRange(-1, 3);//Для оси Oy
//И перерисуем график на нашем widget
ui->widget->replot();
Старый пример
До обновления статьи 2015-12-01 тут был вот такой пример:
// generate some data:
QVector<double> x(101), y(101); // initialize with entries 0..100
for (int i = 0; i < 101; ++i) {
x[i] = i/50.0 - 1; // x goes from -1 to 1
y[i] = x[i] * x[i]; // let's plot a quadratic function
}
// create graph and assign data to it:
ui->widget->addGraph();
ui->widget->graph(0)->setData(x, y);
// give the axes some labels:
ui->widget->xAxis->setLabel("x");
ui->widget->yAxis->setLabel("y");
// set axes ranges, so we see all data:
ui->widget->xAxis->setRange(-1, 1);
ui->widget->yAxis->setRange(0, 1);
ui->widget->replot();
Статья обновлена 2018
Тэги:
- Qt
- Графики
- C++
- Chart
- Plot
Категории:
- blog
- it
- programming
В статье показывается пример установки и демонстрации возможностей библиотеки QCustomPlot для рисования графиков на QtWidgets.
В статье показывается пример установки и демонстрации возможностей библиотеки QCustomPlot для рисования графиков на QtWidgets.