3
$\begingroup$

For simplicity, lets say I have two histograms

hist1 = Histogram[
  RandomVariate[NormalDistribution[0, 0.6], 1000], {-2, 2, 0.2}, 
  0.5 #2 &, ChartStyle -> Green]

enter image description here

hist2 = Histogram[
  RandomVariate[NormalDistribution[0, 1.4], 1000], {-2, 2, 0.2}, 
  0.8 #2 &, ChartStyle -> Blue]

enter image description here

I am looking for a way to stack both the histograms on one another. I have been trying to do it with Show but I am not able to get it. I know that "

Histogram[{RandomVariate[NormalDistribution[0, 0.6], 1000], 
   RandomVariate[NormalDistribution[0, 1.4], 1000]}, {-2, 2, 0.2}, 
 ChartLayout -> "Stacked"]

" will do the job (without taking the scaling of "bin counts" into account).

Is there any way to stack both the histograms taking the height specifications into account?

Your help will be much appreciated!!

$\endgroup$
2
  • 1
    $\begingroup$ Why do you want to do this? It's rather unusual and there may be a better way to achieve your goal. $\endgroup$ – Brett Champion Jul 9 '18 at 2:22
  • $\begingroup$ I have to plot some stacked histograms for my research (My research area is "Particle Physics", I hunt for new particles which could be detected at LHC), where I want to stack all the histograms of "new physics or interesting physics" (called "signal") events (for some variable, such as energy) and then overlap that with another stacked histograms of "known physics or uninteresting physics" (called "backgrounds") events , then see at what value of that variable are the events of the "new physics" more than that of "known physics", so that there is a scope for finding new particles! $\endgroup$ – nick Jul 9 '18 at 4:24
3
$\begingroup$

I did not have any luck with the high-level functions. ChartLayout -> "Stacked" will get you a stacked histogram, but it does not seem possible to specify separate height functions for different datasets. With BarChart I found it difficult to get the ticks on the x-axis right.

It can be done from scratch quite easily:

data1 = RandomVariate[NormalDistribution[0, 0.6], 1000];
{bins, hist1} = HistogramList[data1, {-2, 2, 0.2}, 0.5 #2 &];
data2 = RandomVariate[NormalDistribution[0, 1.4], 1000];
{bins, hist2} = HistogramList[data2, {-2, 2, 0.2}, 0.8 #2 &];
bins = Partition[bins, 2, 1];

histogramBar[{x1_, x2_}, {y1_, y2_}] := Rectangle[{x1, y1}, {x2, y1 + y2}]

bars1 = MapThread[histogramBar, {bins, {ConstantArray[0, Length[hist1]], hist1} // Transpose}];
bars2 = MapThread[histogramBar, {bins, {hist1, hist2} // Transpose}];

Graphics[{
  EdgeForm[Black],
  ColorData[97, 1], bars1,
  ColorData[97, 2], bars2
  },
 Axes -> True,
 AxesOrigin -> {-2, 0},
 AspectRatio -> 1/GoldenRatio
 ]

Mathematica graphics

$\endgroup$
5
  • $\begingroup$ is there a way to stack third histogram to this? I defined third data set, then in the same way I got "hist3" and then I was stuck, I tried defining "bars3" in the similar way, but I am getting wrong results $\endgroup$ – nick Jul 10 '18 at 22:39
  • $\begingroup$ @Prudhvi bars3 = MapThread[histogramBar, {bins, {hist2, hist3} // Transpose}];? $\endgroup$ – C. E. Jul 11 '18 at 0:39
  • $\begingroup$ yes, I tried exactly that, but it is not doing the right thing I guess $\endgroup$ – nick Jul 11 '18 at 0:41
  • $\begingroup$ @Prudhvi Sorry, that's a hasty mistake, it should be: bars3 = MapThread[ histogramBar, {bins, {hist1 + hist2, hist3} // Transpose}]; $\endgroup$ – C. E. Jul 11 '18 at 0:59
  • $\begingroup$ That worked. Thanks much! $\endgroup$ – nick Jul 12 '18 at 7:07
3
$\begingroup$
ClearAll[heightF]
heightF[scales_] := Module[{s = scales}, First[s] #2 /. {s -> (s = RotateLeft[s])} &];

Examples:

SeedRandom[1]
data = RandomVariate[NormalDistribution[0, 0.6], 1000]; 
Histogram[{data, data, data}, {-2, 2, .2}, heightF[{.5, .25, .125}], AspectRatio -> 1,
  ChartLayout -> "Stacked", ChartLegends -> (Row[{"Scale : ", #}] & /@ {.5, .25, .125}) ]

enter image description here

With ChartLayout -> "Overlapped" we see the scaling effect more clearly:

enter image description here

$\endgroup$
2
$\begingroup$

There is likely no known good reason to stack histograms (despite it being done frequently). And if your sample sizes are in the 1,000's, there is even no good reason to display a histogram.

To be able to see "features" that differ among large datasets, you want to use a nonparametric density estimator. Using Mathematica you could do something like the following:

SeedRandom[12345];
x1 = RandomVariate[NormalDistribution[0, 0.6], 1000];
x2 = RandomVariate[NormalDistribution[0, 1.4], 1000];

skd1 = SmoothKernelDistribution[x1];
skd2 = SmoothKernelDistribution[x2];

Plot[{PDF[skd1, x], PDF[skd2, x]}, {x, Min[x1, x2], Max[x1, x2]}]

Two smoothed histograms

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.