(Hello! I have memory consumption problem when trying to output my data to pdf with several pages.
My pipeline is looking kinda like this: I make TCanvas, then in a loop I create some class instance that owns TMultiGraph, then that class gathers some data and draws it via TGraph in the TMultiGraph (mg). After one loop is done, that mg draws to canvas, canvas prints to pdf, then canvas is cleared, and then it starts over.
void create_multigraph_with_tgraph(int index,const char* pdf_filename, bool first, bool last) {
TCanvas* c = new TCanvas(Form("c%d", index), Form("Canvas %d", index), 800, 600);
TMultiGraph* mg = new TMultiGraph();
const int n_points = 1000;
double x[n_points], y[n_points];
TRandom rand;
for (int i = 0; i < n_points; ++i) {
x[i] = rand. Uniform(0, 10);
y[i] = rand. Uniform(0, 10);
}
TGraph* graph = new TGraph(n_points, x, y);
graph->SetTitle(Form("Graph %d", index));
graph->SetMarkerStyle(20);
graph->SetMarkerSize(0.5);
graph->SetMarkerColor(index + 1);
mg->Add(graph);
mg->SetTitle(Form("MultiGraph %d;X axis;Y axis", index));
mg->Draw("AP");
c->SaveAs(Form("graph_%d. png", index));
if (first) {
c->Print(Form("%s(", pdf_filename), "pdf");
} else if (last) {
c->Print(Form("%s)", pdf_filename), "pdf");
} else {
c->Print(pdf_filename, "pdf");
}
delete c;
}
void create_image_pdf(const char* image_pdf_filename, int n_graphs) {
TCanvas* c = new TCanvas("image_canvas", "Image Canvas", 800, 600);
for (int i = 0; i < n_graphs; ++i) {
TString png_filename = Form("graph_%d. png", i);
TImage* img = TImage::Open(png_filename);
if (!img) {
printf("Could not open image file %s\n", png_filename. Data());
continue;
}
c->Clear();
img->Draw();
if (i == 0) {
c->Print(Form("%s(", image_pdf_filename), "pdf");
} else if (i == n_graphs - 1) {
c->Print(Form("%s)", image_pdf_filename), "pdf");
} else {
c->Print(image_pdf_filename, "pdf");
}
delete img;
}
delete c;
}
void create_pdfs(const char* pdf_filename, const char* image_pdf_filename) {
for (int i = 0; i < 10; ++i) {
create_multigraph_with_tgraph(i, pdf_filename, i == 0, i == 9);
}
create_image_pdf(image_pdf_filename, 10);
}
int main() {
const char* pdf_filename = "output. pdf";
const char* image_pdf_filename = "output_images. pdf";
create_pdfs(pdf_filename, image_pdf_filename);
return 0;
}
this is as rough recreation of what is going on in my program. The ROOT calls are actuall scattered across different classes, but that doesnāt affect the result. I, however, discovered that thereās a problem with PDF size. If I rack up the number of points to 100000 per plot (for example), my PDF will be huge (since itās vector), but pngs, being raster, do not take that much space. For 10000 points per plot and 10 plots on pdf I believe the code above gives me about 3.2 mb PDF, ubt cummulative size of pngs is about 1.5 mb. And the more points - the worse (about 150kb pngs x 10 gives me once again 1.5 megs, but the PDF will be around 30+ megs). The whole point of using ROOT was to make code much better than gnuplot, because gnuplot is somewhat hard to incorporate into C++ code. But for some reason gnuplotās PDF plots weigh times less than ROOTās PDF (with same data).
My initial idea was to try and save plots as png and then put it on TCanvas and print to PDF, possibly reducing the final size of PDF.
But as you can see, I attempted it in my code (create_image_pdf()), and it gives āWarning in <TASImage::Paint>: PDF not implemented yet:
ā.
So, my question stands: is there a way to produce multipage PDF, AND reduce the size of it? I believe the problem lies in the fact that too many points for vector image leads to memory consumption by design, unlike raster pics, but Iām willing to try anything else as long as it just ROOT, no standalone apps (i can defo manually stitch with some kind of imagemagick or something else, but I want to get PDF from my app, no other apps)
Also, Iāve definetely seen the same topics on this forum (thereās one called " Saving png logo in ROOT as pdf", i cant put links as new user, it specifiaclly has the same issue with putting pngs on pdf, but only told to go vector), but maybe there are some new ideas regarding this issue?
Thank you in advance!)