← Gallery

Histogram

Measurements across intervals

Explore the example, download the output or use the C# source in your own project.

Preview
Measurements across intervalsChart with 1 data series: Quantity.Measurements across intervalsArithmetic means; the empty interval has no mean0246810Measurement-50510Mean quantity310-6
Measurements across intervals
Measurements across intervalsChart with 1 data series: Quantity.Measurements across intervalsArithmetic means; the empty interval has no mean0246810Measurement-50510Mean quantity310-6
Measurements across intervals
360 × 360 pixels

Create this example

Create a console project, add the ChartForgeX package, and replace Program.cs with this source. Run it to write SVG, PNG and HTML with the default system fonts.

For the same typography as the gallery, download the gallery-font recipe and copy the gallery’s fonts directory beside your program.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using ChartForgeX.Core;
using ChartForgeX.Primitives;
using ChartForgeX.Rendering;
using ChartForgeX.Themes;
using ChartForgeX.Topology;
using ChartForgeX.Typography;
using ChartForgeX.VisualArtifacts;
using ChartForgeX.VisualBlocks;

var mode = VisualThemeMode.Light;
var theme = VisualTheme.Graphite();
var model = HistogramRecipe.Create("compact-mean", mode);
var context = new VisualRenderContext(
    new VisualLayoutOptions(new VisualSize(360, 360)), theme, mode,
    new VisualFrame("Measurements across intervals", "Arithmetic means; the empty interval has no mean", showLegend: false, showSurface: false));
var prepared = model.Prepare(context);
File.WriteAllText("visual.svg", prepared.ToSvg());
File.WriteAllBytes("visual.png", prepared.ToPng());
File.WriteAllText("visual.html", prepared.ToArtifact("example", VisualArtifactKind.Chart).ToHtmlPage());

/// <summary>Counts, density, signed sums or means over the same explicit unequal measurement intervals.</summary>
public static class HistogramRecipe {
    public static Chart Create(string variant = "wide", VisualThemeMode mode = VisualThemeMode.Light) {
        var aggregation = variant.StartsWith("compact-", StringComparison.Ordinal) ? variant.Substring(8) : variant;
        if (aggregation == "compact") aggregation = "wide";
        var layout = ChartHistogramBinLayout.FromBoundaries(new[] { 0d, 1, 3, 6, 10 });
        var chart = Chart.Create().WithXAxis("Measurement").WithDataLabels();
        chart.Options.XAxis.WithBounds(0, 10);
        ChartSeries observations;
        if (aggregation is "wide" or "density") {
            observations = ChartSeries.CreateHistogram(new ChartSeriesId("observations"), "Observations",
                new[] { .2, .4, .8, 1.2, 1.8, 2.5, 6.1, 7.5, 9 }, layout,
                aggregation == "density" ? ChartHistogramEncoding.Density : ChartHistogramEncoding.Value);
            chart.WithYAxis(aggregation == "density" ? "Observations per unit" : "Observation count");
            foreach (var bin in observations.HistogramBins) observations.WithPointLabel(bin.Index, bin.Count + " obs");
        } else if (aggregation is "sum" or "mean") {
            observations = ChartSeries.CreateHistogram(new ChartSeriesId("quantity"), "Quantity",
                new[] { new ChartPoint(.2, 10), new ChartPoint(.4, -4), new ChartPoint(1.2, 8),
                    new ChartPoint(2.5, 12), new ChartPoint(6.1, -4), new ChartPoint(9, -8) }, layout,
                aggregation == "sum" ? ChartHistogramAggregation.Sum : ChartHistogramAggregation.Mean);
            chart.WithYAxis(aggregation == "sum" ? "Total quantity" : "Mean quantity");
        } else throw new ArgumentOutOfRangeException(nameof(variant));
        return chart.AddSeries(observations);
    }
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using ChartForgeX.Core;
using ChartForgeX.Primitives;
using ChartForgeX.Rendering;
using ChartForgeX.Themes;
using ChartForgeX.Topology;
using ChartForgeX.Typography;
using ChartForgeX.VisualArtifacts;
using ChartForgeX.VisualBlocks;

var mode = VisualThemeMode.Dark;
var theme = VisualTheme.Graphite();
var model = HistogramRecipe.Create("compact-mean", mode);
var context = new VisualRenderContext(
    new VisualLayoutOptions(new VisualSize(360, 360)), theme, mode,
    new VisualFrame("Measurements across intervals", "Arithmetic means; the empty interval has no mean", showLegend: false, showSurface: false));
var prepared = model.Prepare(context);
File.WriteAllText("visual.svg", prepared.ToSvg());
File.WriteAllBytes("visual.png", prepared.ToPng());
File.WriteAllText("visual.html", prepared.ToArtifact("example", VisualArtifactKind.Chart).ToHtmlPage());

/// <summary>Counts, density, signed sums or means over the same explicit unequal measurement intervals.</summary>
public static class HistogramRecipe {
    public static Chart Create(string variant = "wide", VisualThemeMode mode = VisualThemeMode.Light) {
        var aggregation = variant.StartsWith("compact-", StringComparison.Ordinal) ? variant.Substring(8) : variant;
        if (aggregation == "compact") aggregation = "wide";
        var layout = ChartHistogramBinLayout.FromBoundaries(new[] { 0d, 1, 3, 6, 10 });
        var chart = Chart.Create().WithXAxis("Measurement").WithDataLabels();
        chart.Options.XAxis.WithBounds(0, 10);
        ChartSeries observations;
        if (aggregation is "wide" or "density") {
            observations = ChartSeries.CreateHistogram(new ChartSeriesId("observations"), "Observations",
                new[] { .2, .4, .8, 1.2, 1.8, 2.5, 6.1, 7.5, 9 }, layout,
                aggregation == "density" ? ChartHistogramEncoding.Density : ChartHistogramEncoding.Value);
            chart.WithYAxis(aggregation == "density" ? "Observations per unit" : "Observation count");
            foreach (var bin in observations.HistogramBins) observations.WithPointLabel(bin.Index, bin.Count + " obs");
        } else if (aggregation is "sum" or "mean") {
            observations = ChartSeries.CreateHistogram(new ChartSeriesId("quantity"), "Quantity",
                new[] { new ChartPoint(.2, 10), new ChartPoint(.4, -4), new ChartPoint(1.2, 8),
                    new ChartPoint(2.5, 12), new ChartPoint(6.1, -4), new ChartPoint(9, -8) }, layout,
                aggregation == "sum" ? ChartHistogramAggregation.Sum : ChartHistogramAggregation.Mean);
            chart.WithYAxis(aggregation == "sum" ? "Total quantity" : "Mean quantity");
        } else throw new ArgumentOutOfRangeException(nameof(variant));
        return chart.AddSeries(observations);
    }
}