2015-03-02 139 views
0

我嘗試習慣Oxyplot在我的C#應用​​程序中創建一些圖表。所以我想用OxyPlot創建一個Boxplot圖,但我無法獲得任何結果。我嘗試了「入門」示例,但沒有任何問題,但現在我不知道如何將數據綁定到BoxplotSeries。我在GitHub上閱讀了關於BoxPlotSeries的文檔,但沒有列出很多信息,這些示例也不能幫助我。那麼有人可以給我一個例子如何使用BoxPlotSeries並將數據綁定到它?C# - 在Oxyplot中創建Boxplot

非常感謝。

回答

0

所以我找到了一種用OxyPlot創建Boxplot的方法。只需使用BoxPlotSeries中的OxyPlot,一個包含Boxplots和一點數學運算的List對象。我使用CategoryAxes作爲x軸來區分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 
} 
0

我不知道你是否想在WPF/XAML中做到這一點,如果答案是肯定的,那麼你目前沒有這種可能性,因爲沒有BoxPlot系列的WPF包裝器。

我試圖將它移植自己,但遇到了一些問題,如果您想參與,請在Github上查看下面的問題:

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

編輯:我剛剛提交pull請求與你應該可以在WPF中使用BoxPlot