Однажды мне нужно было отрисовать пару графиков в консольной программе, написанной на
С++. Можно было решить эту проблему двумя способами:
- Сохранить график в файле и нарисовать его в экселе или другой софтине, м.б. даже в онлайн рисовалке
- Рисовать график прямиком из программы
Первый способ мне не подходил, так как я проводил тестирование алгоритмов, и лишней возней с копированием данных заниматься не хотелось. Второй способ имеет множество решений, но увы я не нашел быстрого решения, чтобы библиотека для рисования не требовала целую кучу зависимостей. Обычно библиотеки для рисования из
С++ программы хотят
OpenCV или питон с матлабом. Еще как вариант я знаю
SFML и
ImGUI. Вопрос — нафига столько всего нужно для обычного графика, если по сути нужен OpenGL и все. Решил исправить эту проблему и набросал
header-only С++ библиотеку, которая работает в отдельном потоке и способна рисовать графики зависимостей X от Y и тепловые карты. Из зависимостей библиотека требует FreeGLUT.
Как установить
Если использовать Code::Blocks и mingw, то нужно подключить библиотеку
freeglut или
freeglut_static (во втором случае нужно также установить макрос FREEGLUT_STATIC), а также
opengl32,
winmm,
gdi32. Подключить в проекте заголовочный файл
include/easy_plot.hpp, указать С++11 или выше.
Пример того, что может рисовать эта библиотека:



Пример кода
#include "easy_plot.hpp"
int main(int argc, char* argv[]) {
easy_plot::init(&argc, argv);
std::vector<double> x = {0,1,0,1,2,0,1};
easy_plot::plot("X", x);
// ставим красный цвет линии
std::vector<double> y = {0,2,3,4,2,0,1};
easy_plot::plot("Y", y, easy_plot::LineSpec(1,0,0));
std::vector<double> x2 = {0,2,6,7,8,10,12};
easy_plot::plot("XY", x2, y, easy_plot::LineSpec(1,1,0));
easy_plot::WindowSpec wstyle; // тут можно настроить стиль графика (цвет фона и пр.)
// выводим три графика в одном
easy_plot::plot<double>("Y1Y2Y3", wstyle, 3, x, easy_plot::LineSpec(1,0,0), x2, easy_plot::LineSpec(1,0,1), y, easy_plot::LineSpec(0,1,0));
while(true) {
std::this_thread::yield();
}
return 0;
}Рисование тепловой карты
#include "easy_plot.hpp"
int main(int argc, char* argv[]) {
easy_plot::init(&argc, argv);
easy_plot::WindowSpec image_wstyle;
image_wstyle.is_grid = true;
image_wstyle.height = 320;
image_wstyle.width = 320;
float image_data[32][32] = {};
size_t image_ind = 0;
for(size_t x = 0 ; x < 32; ++x) {
for(size_t y = 0; y < 32; ++y, ++image_ind) {
image_data[x][y] = 1024 - std::sqrt((x - 18) * (x - 18) + (y - 18) * (y - 18));
}
}
image_wstyle.is_color_heatmap = true;
easy_plot::draw_heatmap("image_heatmap", image_wstyle, &image_data[0][0], 32, 32);
while(true) {
std::this_thread::yield();
}
return 0;
}
Особенности библиотеки:
- Функция plot может принимать такие параметры, как имя окна, стиль окна (различные настройки цвета и пр., см. WindowSpec), данные графиков и стиль линий.
- Функция draw_heatmap может принимать такие параметры, как имя окна, стиль окна (различные настройки цвета и пр., см. WindowSpec), данные массива тепловой карты типа float и размер тепловой карты.
- Если графиков несколько, изначально они будут расположены по всему экрану равномерно.
- Если навести курсор мыши на график, можно узнать номер линии и данные по осям X и Y.
- Рисование графиков и тепловой карты происходит в отдельном потоке.
- При повторном вызове функции с уже существующим именем окна график будет перерисован.
- Можно сохранить график
Репозиторий:
https://github.com/NewYaroslav/easy_plot_cpp