c# - 如何在WFA中将数据添加到BoxPlot?

标签 c# winforms charts boxplot

我正在手动创建箱线图。我有4个double []数组,并且要在图表上显示一些计算结果。我不知道如何用图表系列正确连接我的数组。
这是我的图表:

        Chart chart = new Chart();
        chart.Series.Add("S1");
        chart.Series.Add("S2");
        chart.Series.Add("S3");
        chart.Series.Add("S4");
        chart.ChartAreas.Add("ChartArea1");
        chart.ChartAreas[0].Visible = true;
        chart.ChartAreas[0].Position.Auto = true;
        chart.Series[0].ChartType = SeriesChartType.BoxPlot;
        chart.Series[1].ChartType = SeriesChartType.BoxPlot;
        chart.Series[2].ChartType = SeriesChartType.BoxPlot;
        chart.Series[3].ChartType = SeriesChartType.BoxPlot;

        chart.Parent = this;
        chart.Visible = true;
        double[] yValues = { 2, 3, 4, 5, 4, 5, 5, 2, 1, 9, 20, 4 };//example values
        chart.Series["S1"].Points.DataBindY(yValues);


这就是我得到的:

my failed boxplot

结果,我想要得到这样的东西:example boxplot

最佳答案

您试图将数据绑定到BoxPlot系列。但这仅导致绑定第一个Y值,这意味着您创建了一组“较低晶须”。所有其他5个Y值均为空,即0。因此,您看到的图形很少。


  MSDN:框的值通常是从
  另一个系列中存在的数据。一盒符号(DataPoint
  对象)与一个数据系列相关联。
  
  箱形图系列的数据仍可以使用
  数据绑定,或通过使用Series.Points成员(
  DataPointCollection对象)。


让我们看一下所有这些选项:


使用常规数据绑定。这是您尝试过的,但是语法错误。
您还可以使用DataPointsAddY分别添加箱形图系列本身的AddXY,提供所有6个Y值,即提供统计分析的结果。此处仅使用一个数组,其中包含六个y值。
或者,您可以使用一个或多个数据系列,然后让图表在每个系列的一个框中汇总这些数据。该序列非常正常,读取的可能是PointLine或其他任何内容。它们甚至是不可见的,当然您可以为它们使用数据绑定。-一旦某个数据序列到位,您就可以定义< cc>系列,然后通过将其BoxPlot特殊属性设置为一个字符串,将其“绑定”到数据系列中,在该字符串中可以将“系列”的名称连接起来...


选项1.使用常规数据绑定来输入您拥有的统计信息。

这就是您尝试过的。但是,正确的方法有点令人惊讶。您的数据需要像这样排序:

外部数组(或["BoxPlotSeries"])必须具有六个y值。对于要在框中显示的每个数据集,六个内部数组应包含一个值。让我们看一个包含三个伪造统计数据集的示例:

double[][] yValues = {
            new[]{ 15.6, 24.4, 36.1 },  // Lower whiskers
            new[]{ 46.2, 52.2, 91.9 },  // Upper whiskers
            new[]{ 22.3, 27.2, 55.9 },  // Lower boxes
            new[]{ 33.2, 44.4, 77.9 },  // Upper boxes
            new[]{ 25.2, 38.4, 68.5 },  // Averages and means
            new[]{ 27.4, 32.4, 66.9 }   // Medians
        };


将其绑定到IEnumerable系列BoxPlot后的外观

S1.Points.DataBindY(yValues);


enter image description here

您也可以创建个人系列;请参阅底部的更新!

选项2:自己输入S1数据

让我们看一下第一种方法的示例:在这里,我们需要准备好统计信息。它是BoxPlotList,每个元素包含6个元素:

Random R = new Random(23);
List<double[]> yValues = new List<double[]>();
for (int i = 0; i < 8; i++)
{
    { R.Next(5),      R.Next(5) + 20, R.Next(5) + 3, 
      R.Next(5) + 10, R.Next(5) +  5, R.Next(5) + 7 });
}


现在,我们将这些虚假统计信息添加到double arrays系列中:

S1.ChartType = SeriesChartType.BoxPlot;
S1.Points.Clear();
for (int i = 0; i < yValues.Count; i++ ) S1.Points.Add(new DataPoint(i, yValues[i]));


请注意,每个BoxPlot是由6个双精度数组组成的!

结果如下:

enter image description here

图表现在显示了8个数据集的统计数据,所有数据都是伪造的;-)

选项3a:将一些数据系列与DataPoint关联,然后进行数学运算

另一种用法是让图表进行数学运算:它可以计算您拥有的任意数量的数据系列的统计信息,并为每个数据系列创建一个框。

我们将使用与以前相同的数据集,但是现在它们用于创建6个数据系列,每个数据系列有8个点:

for (int i = 0; i < 6; i++)
{
    Series ds = chart.Series.Add("D" + (i+1));  // set a name D1, D2..
    dx.ChartType = SeriesChartType.Line;
    dx.Points.DataBindY(yValues.Select(x => x[i]).ToArray());
}


它们被绑定到与上面相同的数字,但是现在它们具有不同的含义。因此结果将并且应该看起来不一样!

实际上,您可以查看框和图,并查看它们如何很好地匹配。

注意我给出的数据系列BoxPlot;当我们将它们“绑定”到Names系列时,我们现在将需要它们:

S1.ChartType = SeriesChartType.BoxPlot;
S1["BoxPlotSeries"] = "D1;D2;D3;D4;D5;D6";  // box plot binding!
S1.LegendText = "BoxPlot";


enter image description here

我将引号用于“绑定”,因为它不是真正的数据绑定。取而代之的是,数据系列仅与带有属性属性字符串BoxPlotBoxPlot系列关联。

您的示例包含多个"BoxPlotSeries"系列;这里适用相同的规则。

看看this post,它显示了BoxPlot的另一种用法,包括设置各个颜色。

选项3b:将一些数据系列与您添加到BoxPlot系列的DataPoint相关联;这里也会为我们做数学

虽然选项3a看起来很简单,但我发现没有办法给盒子上色。这是我们可以做到的:

首先,我们强制图表将默认颜色复制到系列中。在此过程中,我们还隐藏BoxPlot项:

S1.Color = Color.Transparent;
S1.LegendText = " ";
chart.ApplyPaletteColors()


然后,我们为每个数据系列在Legend系列DataPoint中创建一个BoxPlot;不是我的系列如何排序:0 = BoxPlot,1-6一些数据系列!您可能需要对此进行调整!

for (int i = 1; i < chart.Series.Count; i++)
{
    DataPoint dp = new DataPoint();
    S1.Points.Add(dp);
    dp["BoxPlotSeries"] =  "D" + i;  // names D1-D6
    dp.Color = chart.Series[i].Color;
}


结果如下:

enter image description here

更新:

您的示例实际上显示了三个箱形图系列;因此,颜色最明显:成簇(即无间隙)显示。

这是将上述数据(来自选项1)绑定到三个单独的框的方法:

for (int i = 0; i < 3; i++)
{
    Series bps = chart.Series.Add("BoxPlotSeries" + i);
    bps.ChartType = SeriesChartType.BoxPlot;
    var yValOne = yValues.Select(x => new[] { x[i] }).ToArray();
    bps.Points.DataBindY(yValOne);
}


enter image description here

最后说明:您的示例代码包含一个包含12个双精度数和4个Boxplot系列的数组。这是没有道理的。您可以将12个值添加到普通序列中,并使用选项3将其与一个箱形图序列相关联。

关于c# - 如何在WFA中将数据添加到BoxPlot?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43524921/

相关文章:

c# - 如何添加像 Point[] 这样的自定义类型以便能够在应用程序设置文件中保存数据?

c# - Winforms:创建动态时间轴控件

c# - 将 KeyDown 事件传递给其他控件

matlab - 如何在 MATLAB 中注释图表?

c# - 图表轴的步长计算

c# - ASP.NET 错误处理问题

c# - 如何在我的项目中引用 TeamFoundation 程序集?

c# - 如果我知道背景颜色,如何创建图像轮廓?

c# - 从 Web 应用程序控制 Winforms 应用程序

javascript - 如何在右中心对齐 Chart JS "legend"