elektroyar
elektroyar личный блог
06 декабря 2019, 11:54

Рисование графиков в С++

Однажды мне нужно было отрисовать пару графиков в консольной программе, написанной на С++. Можно было решить эту проблему двумя способами:
  1. Сохранить график в файле и нарисовать его в экселе или другой софтине, м.б. даже в онлайн рисовалке
  2. Рисовать график прямиком из программы
Первый способ мне не подходил, так как я проводил тестирование алгоритмов, и лишней возней с копированием данных заниматься не хотелось. Второй способ имеет множество решений, но увы я не нашел быстрого решения, чтобы библиотека для рисования не требовала целую кучу зависимостей. Обычно библиотеки для рисования из С++ программы хотят OpenCV или питон с матлабом. Еще как вариант я знаю SFML и ImGUI. Вопрос — нафига столько всего нужно для обычного графика, если по сути нужен OpenGL и все. Решил исправить эту проблему и набросал header-only С++ библиотеку, которая работает в отдельном потоке и способна рисовать графики зависимостей X от Y и тепловые карты. Из зависимостей библиотека требует FreeGLUT.

Как установить


Если использовать Code::Blocks и mingw, то нужно подключить библиотеку freeglut или freeglut_static (во втором случае нужно также установить макрос FREEGLUT_STATIC), а также opengl32winmmgdi32. Подключить в проекте заголовочный файл 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
30 Комментариев
  • Андрей К
    06 декабря 2019, 13:30
    :), а вы решили этот вопрос? веб сервер хороший вариант.
  • Karim
    06 декабря 2019, 13:34
    И зачем такие сложности. Встроенных возможностей вполне хватает и без OpenGL.




  • Skifan
    06 декабря 2019, 14:00
    чет вы походу велосипед собираете 
  • day0markets.ru
    06 декабря 2019, 14:12
    есть же QT, там и графики и интерфейсики

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн