public static PlotModel CreateIndividualBinColors(double mean = 1, int n = 10000) { var model = new PlotModel { Title = "Individual Bin Colors", Subtitle = "Minimum is Red, Maximum is Green" }; model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Frequency" }); model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "Observation" }); Random rnd = new Random(1); HistogramSeries chs = new HistogramSeries() { FillColor = OxyColors.Gray, RenderInLegend = true, Title = "Measurements" }; var binningOptions = new BinningOptions(BinningOutlierMode.CountOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues); var binBreaks = HistogramHelpers.CreateUniformBins(0, 10, 20); var bins = HistogramHelpers.Collect(SampleUniform(rnd, 0, 10, 1000), binBreaks, binningOptions).OrderBy(b => b.Count).ToArray(); bins.First().Color = OxyColors.Red; bins.Last().Color = OxyColors.Green; chs.Items.AddRange(bins); chs.StrokeThickness = 1; model.Series.Add(chs); return(model); }
public void Collect_InvalidParameters() { // valid test data var testSamples = new double[] { 1, 2, 3 }; var testBreaks = new double[] { 1, 2, 3 }; // choice of test options var testOptions = new BinningOptions(BinningOutlierMode.RejectOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues); // disallow null parameters Assert.Throws(typeof(ArgumentNullException), () => HistogramHelpers.Collect(null, testBreaks, testOptions)); Assert.Throws(typeof(ArgumentNullException), () => HistogramHelpers.Collect(testSamples, null, testOptions)); Assert.Throws(typeof(ArgumentNullException), () => HistogramHelpers.Collect(testSamples, testBreaks, null)); // disallow fewer than 2 distinct bin breaks Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(testSamples, new double[] { }, testOptions)); Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(testSamples, new double[] { 1.0 }, testOptions)); Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(testSamples, new double[] { 1.0, 1.0 }, testOptions)); // disallow NaN and infinite samples Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(new double[] { 1.0, double.NaN, 2.0 }, testBreaks, testOptions)); Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(new double[] { 1.0, double.PositiveInfinity, 2.0 }, testBreaks, testOptions)); Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(new double[] { 1.0, double.NegativeInfinity, 2.0 }, testBreaks, testOptions)); // disallow NaN and infinite bin breaks Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(testSamples, new double[] { 1.0, double.NaN, 2.0 }, testOptions)); Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(testSamples, new double[] { 1.0, double.PositiveInfinity, 2.0 }, testOptions)); Assert.Throws(typeof(ArgumentException), () => HistogramHelpers.Collect(testSamples, new double[] { 1.0, double.NegativeInfinity, 2.0 }, testOptions)); // BinningOutlierMode.RejectOutliers disallows outliers Assert.Throws(typeof(ArgumentOutOfRangeException), () => HistogramHelpers.Collect(new double[] { 0.0 }, testBreaks, testOptions)); Assert.Throws(typeof(ArgumentOutOfRangeException), () => HistogramHelpers.Collect(new double[] { 3.0 }, testBreaks, testOptions)); }
public static PlotModel CreateExponentialDistributionCustomBins(double mean = 1, int n = 50000) { var model = new PlotModel { Title = "Exponential Distribution", Subtitle = "Custom bins (" + n + " samples)" }; model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Frequency" }); model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "x" }); Random rnd = new Random(); HistogramSeries chs = new HistogramSeries(); var binningOptions = new BinningOptions(BinningOutlierMode.CountOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues); chs.Items.AddRange(HistogramHelpers.Collect(SampleExps(rnd, 1.0, n), new double[] { 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0, 5.0 }, binningOptions)); chs.StrokeThickness = 1; chs.FillColor = OxyColors.Purple; model.Series.Add(chs); return(model); }
public static PlotModel CreateExponentialDistribution(double mean = 1, int n = 10000) { var model = new PlotModel { Title = "Exponential Distribution", Subtitle = "Uniformly distributed bins (" + n + " samples)" }; model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Frequency" }); model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "x" }); Random rnd = new Random(1); HistogramSeries chs = new HistogramSeries(); var binningOptions = new BinningOptions(BinningOutlierMode.CountOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues); var binBreaks = HistogramHelpers.CreateUniformBins(0, 5, 15); chs.Items.AddRange(HistogramHelpers.Collect(SampleExps(rnd, 1.0, n), binBreaks, binningOptions)); chs.StrokeThickness = 1; model.Series.Add(chs); return(model); }
public void Collect_OutOfOrderBinBreaks() { // binBreaks should be ordered by Collect var sample = new double[] { 2, 3, 9, 8, 7 }; var outOfOrderBreaks = new double[] { 0.0, 10.0, 5.0, 15.0 }; var expectedCounts = new int[] { 2, 3, 0 }; var expectedAreas = new double[] { 0.4, 0.6, 0.0 }; foreach (var binningMode in new[] { BinningOutlierMode.CountOutliers, BinningOutlierMode.IgnoreOutliers }) { var binningOptions = new BinningOptions(binningMode, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues); TestCollect(sample, outOfOrderBreaks, expectedCounts, expectedAreas, binningOptions); } }
public void Collect_OutlierSamples() { // when Collect is unable to bin any items, it should return areas of 0 rather than NaN var outlierSamples = new double[] { -1.0, 2.0, 3.0 }; var breaks = new double[] { 0.0, 1.0, 2.0 }; var expectedCounts = new int[] { 0, 0 }; var expectedAreas = new double[] { 0.0, 0.0 }; foreach (var binningMode in new[] { BinningOutlierMode.CountOutliers, BinningOutlierMode.IgnoreOutliers }) { var binningOptions = new BinningOptions(BinningOutlierMode.IgnoreOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues); TestCollect(outlierSamples, breaks, expectedCounts, expectedAreas, binningOptions); } }
public static PlotModel CreateNormalDistribution(double mean = 0, double std = 1, int n = 1000000) { var model = new PlotModel { Title = $"Normal Distribution (μ={mean}, σ={std})", Subtitle = "95% of the distribution (" + n + " samples)" }; model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Frequency" }); model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "x" }); Random rnd = new Random(); HistogramSeries chs = new HistogramSeries(); var binningOptions = new BinningOptions(BinningOutlierMode.CountOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.ExcludeExtremeValues); var binBreaks = HistogramHelpers.CreateUniformBins(-std * 4, std * 4, 100); chs.Items.AddRange(HistogramHelpers.Collect(SampleNormal(rnd, mean, std, n), binBreaks, binningOptions)); chs.StrokeThickness = 1; double LimitHi = mean + 1.96 * std; double LimitLo = mean - 1.96 * std; OxyColor ColorHi = OxyColors.DarkRed; OxyColor ColorLo = OxyColors.DarkRed; chs.ColorMapping = (item) => { if (item.RangeCenter > LimitHi) { return(ColorHi); } else if (item.RangeCenter < LimitLo) { return(ColorLo); } return(chs.ActualFillColor); }; model.Series.Add(chs); return(model); }
/// <summary> /// Performs a basic test on <see cref="HistogramHelpers.Collect(System.Collections.Generic.IEnumerable{double}, System.Collections.Generic.IReadOnlyList{double}, BinningOptions)"/>. /// </summary> /// <param name="samples">The samples to collect.</param> /// <param name="breaks">The bin breaks that define the bins.</param> /// <param name="expectedCounts">The expected counts.</param> /// <param name="expectedAreas">The expected counts.</param> /// <param name="binningOptions">The binning options to use.</param> private static void TestCollect(double[] samples, double[] breaks, int[] expectedCounts, double[] expectedAreas, BinningOptions binningOptions) { Assume.That(breaks.Length - 1 == expectedCounts.Length); Assume.That(breaks.Length - 1 == expectedAreas.Length); var items = HistogramHelpers.Collect(samples, breaks, binningOptions).ToArray(); // check number of items Assert.AreEqual(expectedAreas.Length, items.Length); // check areas and counts for (int i = 0; i < expectedAreas.Length; i++) { Assert.AreEqual(expectedAreas[i], items[i].Area, expectedAreas[i] * 1E-15); Assert.AreEqual(expectedCounts[i], items[i].Count); } // check item ranges var orderedBreaks = breaks.Distinct().OrderBy(b => b).ToArray(); for (int i = 0; i < items.Length; i++) { Assert.AreEqual(orderedBreaks[i], items[i].RangeStart); Assert.AreEqual(orderedBreaks[i + 1], items[i].RangeEnd); } }
/// <summary> /// Performs a basic test on <see cref="HistogramHelpers.Collect(System.Collections.Generic.IEnumerable{double}, System.Collections.Generic.IReadOnlyList{double}, BinningOptions)"/>. /// </summary> /// <param name="samples">The samples to collect.</param> /// <param name="breaks">The bin breaks that define the bins.</param> /// <param name="expectedCounts">The expected counts.</param> /// <param name="binningOptions">The binning options to use.</param> private static void TestCollect(double[] samples, double[] breaks, int[] expectedCounts, BinningOptions binningOptions) { // compute areas from counts int expectedCount = binningOptions.OutlierMode == BinningOutlierMode.CountOutliers ? samples.Length : expectedCounts.Sum(); Assume.That(expectedCount > 0); var expectedAreas = expectedCounts.Select(c => (double)c / expectedCount).ToArray(); TestCollect(samples, breaks, expectedCounts, expectedAreas, binningOptions); }
public static PlotModel HistogramSeries() { // prepare the model var model = new PlotModel() { Title = "Cubic Distribution", LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.TopCenter, LegendOrientation = LegendOrientation.Horizontal }; // add two linear axes model.Axes.Add(new LinearAxis() { Title = "Observation", Position = AxisPosition.Bottom }); model.Axes.Add(new LinearAxis() { Title = "Frequency", Position = AxisPosition.Left }); // generate random samples from a polynomial distribution double power = 3; double max = 10.0; int sampleCount = 1000; double integral = Math.Pow(max, power + 1) / (power + 1); var rnd = new Random(0); List <double> samples = new List <double>(); for (int i = 0; i < sampleCount; i++) { samples.Add(Math.Pow(rnd.NextDouble() * (power + 1) * integral, 1.0 / (power + 1))); } // plot histogram of samples var histogramSeries = new HistogramSeries() { Title = $"Empirical Distribution", FillColor = OxyColors.Green, StrokeColor = OxyColors.Black, StrokeThickness = 2 }; var bins = HistogramHelpers.CreateUniformBins(0, max, 20); var binningOptions = new BinningOptions(BinningOutlierMode.RejectOutliers, BinningIntervalType.InclusiveLowerBound, BinningExtremeValueMode.IncludeExtremeValues); var items = HistogramHelpers.Collect(samples, bins, binningOptions); histogramSeries.Items.AddRange(items); model.Series.Add(histogramSeries); // plot ideal line for comparison var functionSeries = new FunctionSeries(x => Math.Pow(x, power) / integral, 0, max, 1000) { Title = "Ideal Distribution", Color = OxyColors.Red }; model.Series.Add(functionSeries); return(model); }