You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Is it possible to draw plot into simple buffer? #195
Alright I've perfectly figured this out, the best and easiest way to do this is to modify the matplotlibcpp.h header file, add this code, right below inline void save(const std::string& filename, const int dpi=0):
inline std::vector<uint8_t> save_to_buffer(const int dpi = 0)
{
detail::_interpreter::get();
// Import io module
PyObject* io_module = PyImport_ImportModule("io");
if (!io_module) throw std::runtime_error("Could not import io module");
// Create a BytesIO object
PyObject* bytes_io = PyObject_CallMethod(io_module, "BytesIO", nullptr);
if (!bytes_io) throw std::runtime_error("Could not create BytesIO object");
// Prepare arguments for savefig
PyObject* args = PyTuple_New(1);
PyTuple_SetItem(args, 0, bytes_io);
PyObject* kwargs = PyDict_New();
if (dpi > 0) {
PyDict_SetItemString(kwargs, "dpi", PyLong_FromLong(dpi));
}
PyDict_SetItemString(kwargs, "format", PyUnicode_FromString("png"));
// Call savefig with BytesIO object
PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_save, args, kwargs);
if (!res) throw std::runtime_error("Call to savefig() failed.");
// Get the value from BytesIO
PyObject* getvalue = PyObject_CallMethod(bytes_io, "getvalue", nullptr);
if (!getvalue) throw std::runtime_error("Could not get value from BytesIO");
// Convert the bytes data to a C++ vector
char* data;
Py_ssize_t size;
if (PyBytes_AsStringAndSize(getvalue, &data, &size) == -1)
{
throw std::runtime_error("Could not retrieve data from BytesIO");
}
std::vector<uint8_t> buffer(data, data + size);
// Clean up
Py_DECREF(args);
Py_DECREF(kwargs);
Py_DECREF(res);
Py_DECREF(bytes_io);
Py_DECREF(getvalue);
Py_DECREF(io_module);
return buffer;
}
Here is test example such that, C++ can create a plot using matlibplotcpp, directly store it to buffer, then have OpenCV to access the buffer and view the contents graphically:
/*
How to compile:
cl /EHsc /std:c++17 /I C:\Python312\include /I F:\OpenCV_Course\myenv\Lib\site-packages\numpy\_core\include /I F:\AI_Componets\OpenCV\build\install\include matplotlib_display_pics_from_memory.cpp /link /LIBPATH:F:\AI_Componets\OpenCV\build\install\x64\vc17\lib /LIBPATH:C:\Python312\libs python312.lib opencv_core500.lib opencv_imgcodecs500.lib opencv_highgui500.lib opencv_imgproc500.lib
*/
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <opencv2/opencv.hpp>
#include "F:\OpenCV_Course\matplotlib-cpp\matplotlibcpp.h"
#include <vector>
#include <sstream>
#include <string>
#include <fstream>
using namespace std;
namespace plt = matplotlibcpp;
int main() {
try {
// Prepare data
int ncols = 500, nrows = 300;
std::vector<float> z(ncols * nrows);
for (int j=0; j<nrows; ++j) {
for (int i=0; i<ncols; ++i) {
z.at(ncols * j + i) = std::sin(std::hypot(i - ncols/2, j - nrows/2));
}
}
const float* zptr = &(z[0]);
const int colors = 1;
plt::title("My matrix");
plt::imshow(zptr, nrows, ncols, colors);
// Call the save_to_buffer function
std::vector<uint8_t> buffer = plt::save_to_buffer();
// Decode the buffer into an OpenCV Mat object
cv::Mat image = cv::imdecode(buffer, cv::IMREAD_COLOR);
if (image.empty()) {
throw std::runtime_error("Failed to decode image from buffer");
}
// Display the image using OpenCV
cv::imshow("Plot", image);
cv::waitKey(0);
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Thanks for the request! Rendering a plot into memory fits the project: it is just savefig with an io.BytesIO target, so it stays a thin wrapper. The save_to_buffer snippet posted in this thread is a good starting point for a PR. Ideally it would sit next to plt::save, return a std::vector<uint8_t> with the encoded image, take the image format (e.g. "png") and the usual trailing std::map<std::string, std::string> keywords, throw on failure like save does without leaking references on the error paths, and come with a small example. Until then, saving to a temporary file with plt::save(...) and reading it back into your buffer works on master.
🤖 This triage was made by the project's automated governance process. See the README for details.
Activity
Raj-Uddin commentedon Mar 18, 2025
Have you figured this out?
Raj-Uddin commentedon Mar 18, 2025
Alright I've perfectly figured this out, the best and easiest way to do this is to modify the
matplotlibcpp.hheader file, add this code, right belowinline void save(const std::string& filename, const int dpi=0):Here is test example such that, C++ can create a plot using matlibplotcpp, directly store it to buffer, then have OpenCV to access the buffer and view the contents graphically:
Example Output:

Add changes from lava#195: "Is it possible to draw plot into simple b…
lava commentedon Nov 4, 2026
Thanks for the request! Rendering a plot into memory fits the project: it is just
savefigwith anio.BytesIOtarget, so it stays a thin wrapper. Thesave_to_buffersnippet posted in this thread is a good starting point for a PR. Ideally it would sit next toplt::save, return astd::vector<uint8_t>with the encoded image, take the image format (e.g."png") and the usual trailingstd::map<std::string, std::string>keywords, throw on failure likesavedoes without leaking references on the error paths, and come with a small example. Until then, saving to a temporary file withplt::save(...)and reading it back into your buffer works on master.🤖 This triage was made by the project's automated governance process. See the README for details.