I am attempting to produce plots with consistent styling for use in a publication. My preferred workflow is to save my TCanvas to an SVG file so that I can annotate outside of ROOT and then export to a vector graphics file for the publication (e.g. eps or pdf).
I am having an issue where I cannot figure out how to specify an absolute font size that is respected when saving to SVG (independent of canvas size).
I am aware of the need to select a font with precision >2 to specify absolute font sizes, and indeed this works for getting consistent sizing in the ROOT canvas. However, this does not seem to apply to exported SVG files.
Here is an example:
{
gStyle->SetLabelFont(43);
gStyle->SetLabelSize(16);
TH1F* h = new TH1F("h","",50,-10,10);
h->FillRandom("gaus");
TCanvas* c1 = new TCanvas("c1","Big Canvas",1200,1600);
h->Draw();
TCanvas* c2 = new TCanvas("c2","Small Canvas",150,200);
h->Draw();
c1->SaveAs("c1.svg");
c2->SaveAs("c2.svg");
}
When I run this, c1.svg has a font size of 5.52 pt for the axis labels, according to Inkscape. c2.png has a font size of 42.55 pt. I would like them to be exactly the same (and better yet - easily specifiable in point size, e.g. 10 pt).
In the SVGs the graphics are saved as vectors, not raster (pixels), so pixels don’t have much meaning; thus, the plot elements are saved with the same proportions you see on the canvas when you run the macro (huge labels in the “small” canvas, tiny labels in the “big” canvas). So in this case, try the “normal” font types, which are proportional to the canvas and they may look “wrong” (too small in the small canvas; not actually wrong, but what you chose to do!) in the interactive canvas but “correct” in the SVG; these, for example, seem ok:
Bonus info: since these font sizes are, as I mentioned, proportional to the canvas size, you should make sure your canvases have exactly the same aspect ratio, which is not the case in your example (*); so .035 looks ok but is not perfect.
(*) Note that to control the canvas sizes, use canvas->SetCanvasSize(w,h); the values you gave in the canvas constructor are for the window, meaning that the window decorations will use some of that size, effectively changing the aspect ratios in different ways for different sizes; try for example this:
{
gStyle->SetLabelFont(42);
gStyle->SetLabelSize(.035);
TH1F* h = new TH1F("h","",50,-10,10);
h->FillRandom("gaus");
TCanvas* c1 = new TCanvas("c1","Big Canvas");
c1->SetCanvasSize(1200,1600);
h->Draw();
TCanvas* c2 = new TCanvas("c2","Small Canvas");
c2->SetCanvasSize(150,200);
h->Draw();
c1->SaveAs("c1.svg");
c2->SaveAs("c2.svg");
}
Notice also that in the above, the window sizes are some default value (as I did not specify any values), therefore if you run in the interactive prompt one canvas seems to have white space around it and the other doesn’t fit and the window has scroll bars; but the canvas sizes are as expected both interactively (try resizing the canvas windows by hand to check) and in the saved SVGs.
Okay, thank you. That helps with getting the sizes consistent for sure. Still, if I want a specific point size in the SVG, is there any way to do that - aside from trying to calculate it based on the canvas size and/or guess & check with an output file?
It appears not, but maybe I am still missing something.
Did you use SetCanvasSize() for that? with my example above I get (checked now on Ubuntu + WSL2, but not on web, though, if that makes any difference) both SVGs with the same size:
Indeed that’s not specific to SVG (TSVG.cxx) it is same for PDF and PS: The text size “in pixel” is converted into vector graphics units and the low level backends are not even aware of such conversion. If you compare the SVG display, PDF display to the screen display then size of the text inside the drawing area is the same. So its correct. See the comparison as the “Small canvas” (SVG on the left, PDF in the middle and screen on the right):
See my example with red canvases in order to see better the size of the canvas. The text size in PDF and SVG is correct relatively to the red area. SVG viewer and PDF viewer enlarge the display compare to the display on screen but inside the drawing area (now in red) the size of the text is the same
{
auto t = new TText(.5, .5, "SVG test");
t->SetTextFont(43);
t->SetTextSize(16);
TCanvas* c1 = new TCanvas("c1","Big Canvas",1200,1600);
c1->SetFillColor(2);
t->Draw();
TCanvas* c2 = new TCanvas("c2","Small Canvas",150,200);
c2->SetFillColor(2);
t->Draw();
c1->SaveAs("c1.svg");
c1->SaveAs("c1.pdf");
c2->SaveAs("c2.svg");
c2->SaveAs("c2.pdf");
}