THStack using drawing in wrong order for log scale

When I draw a THStack with log scale, it appears the histograms are drawn in the wrong order. I expect the histogram with the largest integral to appear on the top of the stack. This doesn’t seem to be the case in the attached picture. Is there anything that can cause this? An example of a plot where this is happening is attached.

Here is the approximate code that I’m using:

c = new TCanvas(title.c_str(),title.c_str(),700,700);
hs=new THStack(title.c_str(),"");
hs->Draw("E FHIST");
gStyle->SetOptStat(0);
gStyle->SetOptTitle(kFALSE);
gStyle->SetHistTopMargin(0.5);
gPad->SetLogy(1);

//in a loop:
hs->Add(h,"E");
hs->GetXaxis()->SetTitle(title.c_str());
hs->GetYaxis()->SetTitle("N");
hs->SetMaximum(globalMaxBin*10);
hs->SetMinimum(globalMinBin/10);

//redraw histogram to update changes?
hs->Draw("E FHIST");

Can you provide something less “approximate” we could run to see where the problem is ?
A priori the code you posted is correct.

Hi Coucet,

Thanks for your response. I don’t think I can make a simple version that functions, because the calls are spread out over multiple functions.

Thanks

Just to clarify: are you saying you expect the THStack to order the histograms automatically?

1 Like

Hi behrenhoff,

Yes, in the past I assumed it was sorting them, but I guess this isn’t the case. Is there some way to sort the histograms after adding them to the THStack? I don’t see anything in the reference page.

Thanks

1 Like

They are not sorted. They are displayed in the order you entered them in the stack.
Also “sorting” them would be kind of difficult … what would be the criteria to sort them ? we can think of many …

1 Like

Why not copy the std::sort() practice? You can sort with a function object, struct, etc. It looks like the histograms are stored in a linked list so this would be easy functionality to add.

TList has some sorting tool you can may be get the list of histograms from the stack and use that tool ?

TList claims to have a sorting function, but it looks like it just sorts based on the names of the objects. Looking at the TList::Sort (Bool_t order=kSortAscending) function, it doesn’t appear to have a way to specify the comparison function.

This problem is looks like it wasn’t resolved here:

Actually, I’d suggest to keep your histograms in a std::vector and sort that before adding the histograms to the stack. It seems simpler to me to use standard C++ tools than to check how to sort the internal stack list (is that even legal?).

#include <TH1F.h>
#include <THStack.h>
#include <algorithm>
#include <vector>

void xxx() {
    // create two "random" histograms
    auto h1 = new TH1F("h1", "h1", 10, 0, 10);
    h1->Fill(1, 5);
    h1->Fill(2, 1);
    h1->SetLineColor(kRed);
    auto h2 = new TH1F("h2", "h2", 10, 0, 10);
    h2->Fill(1, 1);
    h2->Fill(2, 10);
    h2->SetLineColor(kBlue);

    std::vector<TH1 *> v = {h1, h2};

    // sort by "smallest integral first"
    std::sort(v.begin(), v.end(),
              [](TH1 *a, TH1 *b) { return a->Integral() < b->Integral(); });

    auto stack = new THStack("Stack", "title");
    for (auto h : v)
        stack->Add(h);
    stack->Draw("hist");
}
1 Like

Hi behrenhoff,

Thanks for the suggestion. Currently this seems like the only choice, but as a container I think THStack should have a sort function. I’m new to ROOT, is there someone responsible for fixing this?

Thanks

I disagree. Containers should NOT have their own general purpose functions. See the STL design. std::vector doesn’t have its own sorting function nor does std::list have it.

Perhaps I should have said “sort functionality” to be more clear. Is THStack iterable? It doesn’t look like it is, since it seems like it would have to inherit from TCollection.

See the STL design.

http://www.cplusplus.com/reference/stl/

THStack is missing most of these, including begin() and end() (as far as I can tell). Would you agree that as a container, THStack should have these functions?

Well, you can iterate over the stack: just iterate over stack->GetHists(). On the other hand, a linked list is certainly not random access, i.e. the corresponding iterator doesn’t have the random_access_iterator_tag and thus you can’t use std::sort anyway.

It is just a bad idea to give all classes you can think of wide interfaces. Keep them short instead.

By saying “STL design” I meant the design as such, more in the sense of Stepanov’s ideas, not so much the begin and end functions of modern C++.

1 Like

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