Monthly TAxis Labels?

I have bunch of data that is accumulated over the course of a year. I want to put all of the data for one year (beginning of January to end of December) in a single plot, and I want the x-axis of the plot to have 12 sub-divisions, where each sub-division represents a month. Ideally, it would centre the name of each month under its respective sub-division.

Right now I’m taking the data, setting the x-axis limits to the beginning and and of the year, dividing the x-axis into 12 divisions, and having it print out the current month at each division. The problem with how I’m trying to do it now is that the number of days in a month varies, so it doesn’t always work as I’d like. The code I’m using is:

xaxis->SetLimits(yearStart, yearEnd);
xaxis->SetNdivisions(12,kFALSE);
xaxis->SetTimeFormat("%b");

What I have now can be viewed here: astroserve.mines.edu/xlf/cal_roo … al.xlf.png

As you can see, it starts at December, skips February, there are two Octobers, and there are two Decembers at the end. For the second December, I would just have to find a way to not display the axis label for the end of the axis, if that’s possible. (As a side note, another weird thing is that if I run the program that makes these graphs twice without unloading the file in between the runs, the axis labels improve a bit to how I’d like them: it starts with two January labels, skips February, but still has the two Decembers).

I’ve considered writing a function that somehow gets the length of the axis and uses that to draw in the months manually, but it seems like there should be a better/easier way of handling this. Any ideas of getting all 12 months to display where they should be, even if they’re just placed at the beginning of each division (rather than centred)?

Can you provide a small running macro showing this behavior ?

Yep, try this.
yearlyPlot.C (900 Bytes)

I see. When you divide a space interval in 12 it will be done in a decimal way based on seconds. Months being all different in length you end up with such effect. In this particular case, where you need only the month displayed, I would suggest you use alphanumeric labels instead of time axis.
root.cern.ch/root/html534/tutori … ls1.C.html
root.cern.ch/root/html534/tutori … ls2.C.html

Ah, thanks. I have the labels working. But now the data points aren’t showing up correctly. My guess is that I’m plotting based on TDatimes, and the histogram’s x-axis doesn’t match up with the times that I want to plot at, so I may need to somehow change the histogram x-axis range to match the time range of my data. But I’m not exactly sure. I’ve attached a new macro to show this, as I’m not quite sure what the issue is at this point.

I actually tried to follow your code, couet, that you posted in this thread: Alphanumeric TGraph labels

In that code, are you drawing a histogram with the desired axis labels, then drawing the TGraph on top of it? Or is there something else going on that I’m not quite getting?

Thanks again for the help so far.
yearlyPlot.C (1.3 KB)

I think in your case we can do much simpler:

{
   const Int_t n = 12;
   char* months[n] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
   TH1F *h = new TH1F("h","test",n,0,1.1);
   h->GetXaxis()->SetNdivisions(-n);
   for (i=0;i<n;i++) h->Fill(months[i],10*sin(i*0.1+0.2));
   h->Draw();
}

The only think you have to find yourself is the 2nd parameter of Fill…

Ah, yeah that actually looks really good. But I’m still a bit confused about how I’d handle this with a histogram. It looks like we have 12 bins here. But I’m not plotting a distribution based on the months, I’m plotting discrete data values that all happen at different times throughout each month (an example can be seen in my first post). Is there a simple way to do this that I’m not seeing?

Thanks again for the help, I’m pretty new to Root and I’m trying to understand all of the tools that it has to offer.

it depends how precise you want to be. All the bins have the same width in the example I sent you.
Is it ok to plot a graph on top of it ?

Yes, I think the fact that they’re evenly spaced will be alright. It obviously wouldn’t be as accurate as it could be, but there are monthly graphs for this data with accurate dates so it should be fine.

In that case it is enough to draw the graph on top of the historgam.

Graph->Draw(“L”)

Sorry, I’ve been pretty busy and haven’t had time to work on this. But I tried doing what you said, and I’m not quite sure what I’m doing wrong. I also don’t know why you suggested that I use 'Graph->Draw(“L”), because I’m trying to draw a bunch of individual markers at each point, not a line/curve.

I think part of my problem is the options to specify when calling the draw() function. It won’t draw the graph with the actual data unless I use the “A” option to draw the axes, but then it all draws over the histogram that has the correclty formatted dates.

I’ve attached a working macro. In line 38, where it says plot->Draw("*A"), if the A option is removed, then the histogram is shown, otherwise the graph with the correct data but a bunch of numbers along the x-axis is shown.
yearlyPlot.C (1.07 KB)

#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <stdio.h>

void yearlyPlot(){
        Long64_t year = 2013;
        const Int_t n = 12;
        char* months[n] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
        int X0 = TDatime(1995,01,01,00,00,00).Convert();
        int startDate = TDatime(year, 01, 01, 00, 00, 00).Convert() - X0;
        int endDate = TDatime(year, 12, 31, 23, 59, 59).Convert() - X0;
        int timeData[n]={0};
        int yData[n]={0};
        TCanvas *canvas = new TCanvas("canvas","Yearly Plot",1500,900);

        for (Long64_t j=0; j < n; j++){
                timeData[j] = TDatime(year, j+1, 01, 00, 00, 00).Convert() - X0;
                yData[j] = 3*j+2;
        }

        TGraph *plot = new TGraph(n,timeData,yData);

        TH1F *h = new TH1F("h","test",n,startDate,endDate);
        h->GetXaxis()->SetNdivisions(-n);
        for (j=0;j<n;j++) h->Fill(months[j],0);
        h->SetMinimum(0);
        h->SetMaximum(40);
        h->Draw();

        plot->Draw("*");
}