4

I've got a data set similar to the first and fourth column of this table http://mathworld.wolfram.com/FrequencyDistribution.html where the first column is the midpoint of a fixed range of values (although a solution with arbitrarily spaced segments would be great) and the second column is the corresponding relative frequency of that initial range of values being present.

 A = {{5, 0.0123445}, {15, 0.0342565}, {25, 0.0885784}, {35, 0.184694}, {45, 0.243735}, {55, 0.223433}, {65, 0.111512}, {75, 0.000000}, {85, 0.000000}, {95, 0.1014466}}

I want to plot a histogram/discrete probability distribution. I've found solutions to plotting histograms from pre-binned data https://stackoverflow.com/questions/15117024/histogram-with-frequency-data but this only works on integer values.

My probability data has ~6 significant digits and I would really prefer not to arbitrarily multiply my data by 10^6 to plot it then adjust the plot labels to divide by 10^6.

Am I trying to force a function to do something it's not designed to do, is there a better way of going about this?

Thanks!

Andrew Stewart
  • 421
  • 2
  • 9

6 Answers6

3

Maybe a simple BarChart with labels would suffice?

BarChart[list[[All, 2]], ChartLabels -> list[[All, 1]]]

enter image description here

Total@list[[All, 2]]

1.

Update

Unevenly spaced segments

list =
  {{5, 0.0123445}, {35, 0.0342565}, {45, 0.0885784}, {50, 0.184694},
   {52, 0.243735}, {55, 0.223433}, {65, 0.111512}, {75, 
    0.000000}, {85, 0.000000}, {95, 0.1014466}};

BarChart[list[[All, 2]], ChartLabels -> list[[All, 1]]]

enter image description here

eldo
  • 67,911
  • 5
  • 60
  • 168
  • Would this work with unevenly spaced segments? – Andrew Stewart Jan 13 '16 at 00:18
  • Yes, only the label numbers would change, see update of my answer – eldo Jan 13 '16 at 00:36
  • Thanks for the help, I'm not as familiar with the Charting functions. I would prefer to keep logical spacing on the 'x-axis' while simultaneously being able to set plotrange and independent plot markers etc.

    (Using your methodology on my data yields this plot http://i.imgur.com/pJzIGnN.png which is great but not ideal, re: x-axis).

    – Andrew Stewart Jan 13 '16 at 00:39
3

You could simulate using EmpiricalDistribution. In the following I have changed A to a:

ed = EmpiricalDistribution[#2 -> #1 & @@ (Transpose@a)];
Histogram[RandomVariate[ed, 10000], Automatic, "Probability"]

enter image description here

ubpdqn
  • 60,617
  • 3
  • 59
  • 148
  • Interesting, I think I might use this answer if an exact solution isn't possible. I bumped the 10000 to 10^7 and while it takes a few seconds to run it gives me relatively non-variable output. Thanks! – Andrew Stewart Jan 13 '16 at 01:05
3

Alternatively, you could use WeightedData.

a = {{5, 0.0123445}, {15, 0.0342565}, {25, 0.0885784}, {35, 
   0.184694}, {45, 0.243735}, {55, 0.223433}, {65, 0.111512}, {75, 
   0.000000}, {85, 0.000000}, {95, 0.1014466}};

Histogram[WeightedData @@ Transpose[a], Length[a]]

enter image description here

You might also consider using DiscretePlot with an EmpiricalDistribution.

dist = EmpiricalDistribution[WeightedData @@ Transpose[a]]

DiscretePlot[PDF[dist, x], {x, a[[All, 1]]}, ExtentSize -> Full]

enter image description here

Andy Ross
  • 19,320
  • 2
  • 61
  • 93
3

If you are simply interested in plotting the data, you can use ListStepPlot:

ListStepPlot[A, "Center", Filling -> Axis, Joined -> False]

plot1

Notes

  1. This will work with unevenly-spaced segments, since with the "Center" option, "the step extends to the center between neighboring points:"

    B = {{5, 0.0123445}, {15, 0.0342565}, {22, 0.0885784}, {38, 0.184694}, {42, 0.243735}, 
         {55, 0.223433}, {65, 0.1115120}, {70, 0.0000000}, {85, 0.000000}, {95, 0.101447}};
    
    ListStepPlot[B, "Center", Filling -> Axis, Joined -> False]
    

    plot3

    If you want to specify the right or left point instead, you can use the "Left" or "Right" options instead.

  2. Since this is a plot, and not a chart, some of the nicer chart features are unavailable, and you will need to do more work to get the same result. For instance, if you want to be able to add labels (à la ChartLabels), you can use Labeled like so

    C = Labeled[#, Chop@Round[Last@#, 0.001], Above] & /@ A;
    
    ListStepPlot[C, "Center",
     Filling -> Axis,
     Joined -> False,
     ImagePadding -> {{Automatic, Automatic}, {Automatic, 10}},
     PlotMarkers -> "",
     PlotRangeClipping -> False]
    

    plot2

Virgil
  • 3,437
  • 16
  • 27
1

Similarl output to the above could be achieved using:

Code:

RectangleChart[a, ChartLabels -> a[[All, 1]], BarSpacing -> {10, 5}]

Output:

output

e.doroskevic
  • 5,959
  • 1
  • 13
  • 32
1

You can use the data on frequencies as the third argument of Histogram:

{bincenters, frequencies} = Transpose[A];
spacing = First@Differences@bincenters;
bins = Append[bincenters - spacing/2, Last[bincenters] + spacing/2];

Histogram[{0}, {bins}, frequencies&, ChartStyle -> "Rainbow", 
 AspectRatio -> 1, Ticks -> {bincenters, Automatic}]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
  • Yes, this is the same kind of technique that I used in this answer: https://mathematica.stackexchange.com/questions/81155/how-to-create-a-bar-chart-from-a-list-of-heights-and-bin-delimiter-positions/151319#151319 – hftf Aug 19 '17 at 09:00