Gnuplot - знакомая многим пользователям линукса свободная кросс-платформенная программа, позволяющая строить двухмерные и трехмерные графики. К сожалению, в Qt нет встроенного виджета для отрисовки графиков, но есть сторонние библиотеки позволяющие это сделать. Так есть QwtPlot3D (последний раз обновлялся в 2007 году) для отрисовки трехмерных графиков, для двухмерных графиков есть, например, Qwt. Но сегодня пойдет речь о Gnuplot-iostream interface, позволяющему использовать всю мощь программы gnuplot с минимумом затрат. Эта библиотека представляет собой iostream pipe, независимый от используемой платформы. И так, приступим.
Для начала нам понадобятся сама библиотека, представляющая собой один-единственный заголовочный файл, установленное приложение gnuplot и установленная библиотека Boost (как устанавливать описано тут).
В Windows необходимо также добавить путь к приложению gnuplot в системную переменную Path (например, этот путь может быть следующим C:\Program Files (x86)\gnuplot\bin). Для работы с gnuplot-iostream понадобится также подключить три библиотеки из Boost: filesystem, system и iostreams. Необходимо соблюдать именно такой порядок, иначе получим ошибку. Пример файла проекта Qt:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#------------------------------------------------- | |
# | |
# Project created by QtCreator 2016-01-11T16:59:58 | |
# | |
#------------------------------------------------- | |
QT += core gui | |
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets | |
TARGET = qgnuplot | |
TEMPLATE = app | |
SOURCES += main.cpp\ | |
mainwindow.cpp | |
HEADERS += mainwindow.h \ | |
gnuplot-iostream.h | |
win32 { | |
BOOSTPATH = D:/Qt/boost_1_60_0 | |
BOOSTVER = 1_60 | |
MINGWVER = 48 | |
INCLUDEPATH += $$BOOSTPATH | |
LIBS += -L$$BOOSTPATH/stage/lib \ | |
-llibboost_filesystem-mgw$$MINGWVER-mt-$$BOOSTVER \ | |
-llibboost_system-mgw$$MINGWVER-mt-$$BOOSTVER \ | |
-llibboost_iostreams-mgw$$MINGWVER-mt-$$BOOSTVER | |
} | |
unix { | |
LIBS += -lboost_filesystem \ | |
-lboost_system \ | |
-lboost_iostreams | |
} |
#include "gnuplot-iostream.h"
Использование gnuplot-iostream выглядит следующим образом:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef _WIN32 | |
Gnuplot gp("gnuplot.exe -persist"); | |
#else | |
Gnuplot gp; | |
#endif | |
std::string expr = "x**2 - y**2"; | |
gp << "f(x,y)=" << expr << "\n"; | |
gp << "splot f(x,y) with pm3d palette title 'f(x,y)=" << expr << "'\n"; |
Рассмотрим простой пример. На главном окне (MainWindow) будет располагаться поле для ввода уравнения f(x,y) и две кнопки. По клику на одну кнопку мы строим через приложение gnuplot график уравнения f(x,y), по клику по другой кнопке мы строим выводим график заданного массива точек (x,y,z).
Файл проекта приведен выше. Заголовочный файл главного окна mainwindow.h:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MAINWINDOW_H | |
#define MAINWINDOW_H | |
#include <QMainWindow> | |
#include <QVBoxLayout> | |
#include <QLabel> | |
#include <QPushButton> | |
#include <QLineEdit> | |
#include <gnuplot-iostream.h> //библиотека для работы с gnuplot | |
class MainWindow : public QMainWindow | |
{ | |
Q_OBJECT | |
public: | |
MainWindow(QWidget *parent = 0); | |
~MainWindow(); | |
private slots: | |
void on_plot_expr(); //отрисовка графика по заданному выражению | |
void on_plot_array(); //отрисовка графика из заданного массива | |
private: | |
QLineEdit *expr; //выражение для f(x,y) | |
QPushButton *plot_expr; //кнопка для отрисовки графика по заданному выражению | |
QPushButton *plot_array; //кнопка для отрисовки графика из заданного массива | |
}; | |
#endif // MAINWINDOW_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "mainwindow.h" | |
MainWindow::MainWindow(QWidget *parent) | |
: QMainWindow(parent) | |
{ | |
//Создаем главный виджет | |
QWidget *main = new QWidget; | |
setCentralWidget(main); | |
//На главном виджете размещаем вертикальный layout | |
QVBoxLayout *main_layout = new QVBoxLayout; | |
main->setLayout(main_layout); | |
QLabel *lbl = new QLabel; | |
lbl->setText("f(x,y)="); | |
main_layout->addWidget(lbl); | |
//Поле для ввода выражения f(x,y) | |
expr = new QLineEdit; | |
expr->setText("x**2 + y**2"); | |
main_layout->addWidget(expr); | |
//Кнопка отрисовки графика для выражения f(x,y) | |
plot_expr = new QPushButton; | |
plot_expr->setText("Plot expression"); | |
main_layout->addWidget(plot_expr); | |
connect(plot_expr, SIGNAL(clicked()), this, SLOT(on_plot_expr())); | |
//Кнопка отрисовки заданного массива | |
plot_array = new QPushButton; | |
plot_array->setText("Plot array"); | |
main_layout->addWidget(plot_array); | |
connect(plot_array, SIGNAL(clicked()), this, SLOT(on_plot_array())); | |
} | |
MainWindow::~MainWindow() | |
{ | |
} | |
void MainWindow::on_plot_expr() | |
{ | |
#ifdef _WIN32 | |
Gnuplot gp("gnuplot.exe -persist"); | |
#else | |
Gnuplot gp; | |
#endif | |
gp << "f(x,y)=" << expr->text().toStdString() << "\n"; | |
gp << "splot f(x,y) with pm3d palette title 'f(x,y)=" << expr->text().toStdString() << "'\n"; | |
} | |
void MainWindow::on_plot_array() | |
{ | |
#ifdef _WIN32 | |
Gnuplot gp("gnuplot.exe -persist"); | |
#else | |
Gnuplot gp; | |
#endif | |
int size = 100; | |
QVector<QVector<double> > arr(size*size); | |
for (int i = 0; i < size; ++i) | |
for (int j = 0; j < size; ++j) | |
{ | |
arr[j + size*i].append(i); | |
arr[j + size*i].append(j); | |
arr[j + size*i].append((i*i - j*j)/size); | |
} | |
gp << "f(x,y)=" << expr->text().toStdString() << "\n"; | |
gp << "splot '-' with dots palette title 'Plotting the array'\n"; | |
gp.send1d(arr); | |
} |
Комментариев нет:
Отправить комментарий