简体   繁体   English

C# - 在Oxyplot中创建一个Boxplot

[英]C# - Creating a Boxplot in Oxyplot

I try to get used to Oxyplot to create some charts in my C# application. 我尝试习惯Oxyplot在我的C#应用​​程序中创建一些图表。 So I wanted to create a Boxplot diagram with OxyPlot, but I am not able to get any results. 所以我想用OxyPlot创建一个Boxplot图,但我无法得到任何结果。 I tried the "Getting Started" example with no problems but now I have no clue how to bind data to a BoxplotSeries . 我尝试了“入门”示例没有问题,但现在我不知道如何将数据绑定到BoxplotSeries I read the documentation on GitHub for BoxPlotSeries but there are not much information listed and the examples help me neither. 我在GitHub上阅读了BoxPlotSeries的文档,但没有列出太多信息,这些例子也没有帮助我。 So can somebody can give me an example how to use BoxPlotSeries and bind data to it? 那么有人可以举个例子来说明如何使用BoxPlotSeries并将数据绑定到它吗?

Thank you so much. 非常感谢。

I don't know if you want to do it in WPF/XAML, if the answer is yes then you currently don't have the possibility to do it as there is no WPF wrapper for the BoxPlot Series. 我不知道你是否想在WPF / XAML中这样做,如果答案是肯定的,那么你目前无法做到这一点,因为BoxPlot系列没有WPF包装器。

I tried to port it myself, but ran into some problems, if you want to contribute please see the issue below on GitHub: 我试图自己移植它,但遇到了一些问题,如果你想贡献请在GitHub上看下面的问题:

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

EDIT: I just submitted a pull request with which you should be able to use a BoxPlot in WPF 编辑:我刚刚提交了一个pull请求,您应该能够在WPF中使用BoxPlot

So I found a way to create a Boxplot with OxyPlot. 所以我找到了一种用OxyPlot创建Boxplot的方法。 Just use the Class BoxPlotSeries of OxyPlot, a List object which holds the Boxplots and a little bit of math. 只需使用OxyPlot的Class BoxPlotSeries,这是一个List对象,它包含Boxplots和一些数学运算。 I used CategoryAxes for x axis to distinguish the Boxplots. 我使用CategoryAxes作为x轴来区分Boxplots。

So for the future, here is the Code if somebody struggles with the same problem. 因此,对于未来,如果有人在解决同样的问题,那么这就是守则。

 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM