Modify axis of existing TCanvas

Dear Experts,
I’m trying to modify the label size and offset of a already drawn canvas.
My starting point is only a pointer to some TCanvas, lets call it _obj, that also may have more than one pads.
I use a static function from a custom ‘toolset’ class that picks up this canvas and stores it in different versions (.tex, .png) to disk. Now I would like to add the option to store 2-3 variants of different axis-sizes. This is motivated through the fact that it would be a pain in the a** to have each canvas created and drawn in different sizes.
By now I tried the following with It’s various combinations that may be commented:

  int nPads = ( (TList*) _obj->GetListOfPrimitives() )->GetSize();
  for (int i = 0; i<nPads; i++)
      gStyle->SetLabelOffset(0.005, "X");
      gStyle->SetLabelSize(0.10, "X"); //0.04

The only thing that caused an effect was calling “UseCurrentStyle()” directly on the canvas, but this messes up the Style of all histograms and graphs inside the pads.
Do you have a solution to this problem? Maybe I can copy the style of the current TCanvas, modify and reapply it?


ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided

Yes, doing that, you apply the whole style which include many things which need to be defined. You cannot get the style of a canvas from the canvas it self. But if you know what was that style you can start from it, modify what you want and apply it it using “useCurrentStyle”

Ok, so I could pass the TStyle of the main script to my function, modify and apply it there. In the main script I apply different settings like color etc. to the different objects before I draw them. Is there a way that I can get the current Style of all objects in the main script?
Maybe “gROOT->GetStyle( style_name )” is the way to go, but I have no clue how the style is named and if the styles of individual objects will be stored there as well.

The current style is pointed by the global pointer gStyle

But this gStyle does not host the style of the individual objects. And it being a global pointer its the same style that messes up my histograms. So even if I use gStyle->xx in the main script to set any parameter and apply this style this will mess up my histograms.

I think that you will agree with me that it would be and is an unnecessary overhead to apply each scaling-version to every object I create and save this to separate canvi and so on. There must be an easier approach!?

Can you post your canvas and tell me what you need to change. I will see what I can do

Hi couet,
thank you for taking a look! I have created a small example that recreates my situation.
test.cpp (1.7 KB)

The “testDraw()” function emulates or is basically like my static function I call in my scripts via a toolset-class. In this function I want to be able to: 1) save as is, 2) scale axis, labels, axis-titles and save.

I am not sure I understand where is the problem.
In testDraw() you do
gStyle->SetLabelSize(0.06, “X”);
and that is visible on the plot … so that’s what you want ? seems fine for me

True, but besides that it also changes the style of the histograms and graph.
In case of my example the colours I set for the individual objects change from black/red to blue.
Not in the example but in in my script I see that all colours and styles of lines, fills etc. get reset to the default values when I call “gROOT->ForceStyle()”, set gStyle-attributes before “xx->Draw()” or apply the gStyle-attributes via “canvas->UseCurrentStyle();”.
What I want to achieve is to change only the size and offset of the axis label and title in an existing canvas. This should happen after all objects are drawn to the canvas and before I save a pdf or latex-copy of the canvas. I need this as I want to save two additional versions of the plot with bigger labels and titles so that after downscaling e.g. in latex the text ramains readable and has got a similar size as in the default unscaled plot.

I do not see how to do that with styles. The whole style will apply on the object in the canvas and the individual setting you did are overwritten. Usually we do the opposite: apply a style for the general settings and then modify the individual attributes if needed. I guess you need to have a different approach. May be execute your macro twice with 2 different styles. One having small labels and one having big labels.

Yes, I guess this is how it has to be done. Unfortunately this triples runtime which is in some cases not an option, especially if we are speaking of runtimes around hours. Saving the plots to root files won’t solve the issue either as you have the same initial state.
At his point I think I will have to live with that.

However, saved in a root file, you now can manipulate the axis-style by using the editor by clicking on the axis. I had the Idea to loop over all objects in the canvas and setting the style there but learned that the axis are not accessible via code but only in the editor of e.g a TBrowser. This is a funny circumstance that shows me that the objects are somehow accessible individually.
So will one see a change there at some point? I can’t believe that I’m the only one trying to accomplish such things.

Yes instead of trying to work with styles, you can also retrieve the axis object in the canvas and change the labels size on that particular object.

Oh, ok. I must have missed this option! Can you point me to that?

#include <iostream>
#include <TCanvas.h>
#include <TH1D.h>
#include <TRandom.h>

void testDraw(TCanvas* _obj)
   // draw canvas as is

   int nPads = ( (TList*) _obj->GetListOfPrimitives() )->GetSize();
   TPad *p;
   TList *l;
   TH1 *h;

   for (int i = 0; i<nPads; i++) {
      p = (TPad*)_obj->cd(i+1);
      l = p->GetListOfPrimitives();

      TIter next(l);
      TObject *obj;

      while ((obj = next())) {
         if(obj->InheritsFrom(TH1::Class()) ) {
            h = (TH1*)obj;
            h->SetLabelOffset(0.005, "X");
            h->SetLabelSize(0.06, "X");



void test()
  TRandom *rand = new TRandom(1234);

  TCanvas *c1 = new TCanvas("c1","c1",800,500);

  // 1st pad

  TH1D *h1 = new TH1D("h1", "h1", 10, 0., 2.);
  for (int i = 0; i<10; i++){ h1->SetBinContent( i, rand->Uniform(0.,10.) ); }

  double x[100], y[100]; int n(20);
  for (Int_t i=0;i<n;i++) {
    x[i] = i*0.1;
    y[i] = 10.*sin(x[i]+0.2);
  TGraph* gr = new TGraph(n,x,y);


  // 2nd pad

  TH1D *h2 = new TH1D("h2", "h2", 10, 0., 2.);
  TH1D *h3 = new TH1D("h3", "h3", 10, 0., 2.);
  for (int i = 0; i<10; i++)
      h2->SetBinContent( i, rand->Uniform(0.,10.) );
      h3->SetBinContent( i, rand->Uniform(0.,10.) );


  // test draw/save
  // call scale-draw/save


1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.