C#-在Oxyplot中创建Boxplot

本文关键字:创建 Boxplot Oxyplot C#- | 更新日期: 2024-09-22 22:51:29

我试着习惯Oxyplot在我的C#应用程序中创建一些图表。所以我想用OxyPlot创建一个Boxplot图,但我无法得到任何结果。我尝试了"入门"示例,没有遇到任何问题,但现在我不知道如何将数据绑定到BoxplotSeries。我在GitHub上阅读了BoxPlotSeries的文档,但没有列出太多信息,这些示例对我也没有帮助。那么,有人能给我一个如何使用BoxPlotSeries并将数据绑定到它的例子吗?

非常感谢。

C#-在Oxyplot中创建Boxplot

所以我找到了一种用OxyPlot创建Boxplot的方法。只需使用OxyPlot的类BoxPlotSeries,一个包含BoxPlot和一点数学的List对象。我使用x轴的CategoryAxes来区分Boxplots。

因此,对于未来,如果有人遇到同样的问题,这里是《准则》。

 public class Item
{
    #region Public Properties
    public string Label { get; set; }
    #endregion Public Properties
}
public class BoxPlotSeriesExample
{
    #region Public Constructors
    public BoxPlotSeriesExample()
    {
    }
    #endregion Public Constructors
    #region Public Methods
    public PlotModel createBoxPlot()
    {
        const int boxes = 16;
        var plot = new PlotModel();
        var items = new Collection<Item>();
        for (int i = 1; i < boxes + 1; i++)
        {
            items.Add(new Item { Label = i.ToString() });
        }
        plot.Axes.Add(new LinearAxis
        {
            Position = AxisPosition.Left,
            MajorStep = 1,
            MinorStep = 0.25,
            TickStyle = TickStyle.Crossing,
            AbsoluteMaximum = 5.25,
            AbsoluteMinimum = -0.25
        });
        plot.Axes.Add(new CategoryAxis
        {
            Position = AxisPosition.Bottom,
            ItemsSource = items,
            LabelField = "Label",
            IsTickCentered = true,
            TickStyle = TickStyle.None,
            AbsoluteMinimum = -1,
            AbsoluteMaximum = 17,
            IsZoomEnabled = false
        });
        var lineAnnotation = new LineAnnotation
        {
            Type = LineAnnotationType.Horizontal,
            Y = 5,
            LineStyle = LineStyle.Dash,
            StrokeThickness = 2,
            Color = OxyColor.FromArgb(50, 0, 0, 0)
        };
        plot.Annotations.Add(lineAnnotation);
        lineAnnotation = new LineAnnotation
        {
            Type = LineAnnotationType.Horizontal,
            Y = 1,
            LineStyle = LineStyle.Dash,
            StrokeThickness = 1.5,
            Color = OxyColor.FromArgb(50, 0, 0, 0)
        };
        plot.Annotations.Add(lineAnnotation);
        lineAnnotation = new LineAnnotation
        {
            Type = LineAnnotationType.Horizontal,
            Y = 4,
            LineStyle = LineStyle.Solid,
            StrokeThickness = 1.5,
            Color = OxyColor.FromArgb(50, 0, 0, 0)
        };
        plot.Annotations.Add(lineAnnotation);
        lineAnnotation = new LineAnnotation
        {
            Type = LineAnnotationType.Horizontal,
            Y = 2,
            LineStyle = LineStyle.Solid,
            StrokeThickness = 1.5,
            Color = OxyColor.FromArgb(50, 0, 0, 0)
        };
        plot.Annotations.Add(lineAnnotation);
        var s1 = new BoxPlotSeries();
        s1.Fill = OxyColor.FromRgb(0x1e, 0xb4, 0xda);
        s1.StrokeThickness = 1.1;
        s1.WhiskerWidth = 1;
        var random = new Random();
        for (int i = 0; i < boxes; i++)
        {
            double x = i;
            var points = 5 + random.Next(15);
            var values = new List<double>();
            for (int j = 0; j < points; j++)
            {
                values.Add((random.NextDouble()) * 5);
            }
            values.Sort();
            var median = getMedian(values);
            int r = values.Count % 2;
            double firstQuartil = getMedian(values.Take((values.Count + r) / 2)); // 25%-Quartil
            double thirdQuartil = getMedian(values.Skip((values.Count - r) / 2)); // 75%-Quartil
            var iqr = thirdQuartil - firstQuartil; // Quartilabstand
            var step = 1.5 * iqr;
            var upperWhisker = thirdQuartil + step;
            upperWhisker = values.Where(v => v <= upperWhisker).Max();
            var lowerWhisker = firstQuartil - step;
            lowerWhisker = values.Where(v => v >= lowerWhisker).Min();
            var outliers = values.Where(v => v > upperWhisker || v < lowerWhisker).ToList();
            s1.Items.Add(new BoxPlotItem(x, lowerWhisker, firstQuartil, median, thirdQuartil, upperWhisker, outliers));
        }
        plot.Series.Add(s1);
        return plot;
    }
    #endregion Public Methods
    #region Private Methods
    private static double getMedian(IEnumerable<double> values)
    {
        var sortedInterval = new List<double>(values);
        sortedInterval.Sort();
        var count = sortedInterval.Count;
        if (count % 2 == 1)
        {
            return sortedInterval[(count - 1) / 2];
        }
        return 0.5 * sortedInterval[count / 2] + 0.5 * sortedInterval[(count / 2) - 1];
    }
    #endregion Private Methods
}

我不知道你是否想在WPF/XAML中进行,如果答案是肯定的,那么你目前不可能进行,因为BoxPlot系列没有WPF包装。

我试着自己移植它,但遇到了一些问题,如果你想贡献,请在GitHub:上查看下面的问题

https://github.com/oxyplot/oxyplot/issues/425

编辑:我刚刚提交了一个拉取请求,您应该能够使用WPF 中的BoxPlot