如何在 WFA 中将数据添加到 BoxPlot? [英] How to add data to BoxPlot in WFA?

查看:23
本文介绍了如何在 WFA 中将数据添加到 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 };//示例值chart.Series["S1"].Points.DataBindY(yValues);

这是我得到的:

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

解决方案

您已尝试将数据绑定到 BoxPlot 系列.但这只会导致绑定第一个 Y 值,这意味着您创建了一组较低的胡须".所有其他 5 个 Y 值都为空,即 0.因此,您看到的图形微薄..

<块引用>

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

选项 2:自己输入 BoxPlot 数据

让我们看第一种方式的例子:这里我们需要准备好统计数据.首先我创建一个随机数据结构;它是 double 数组List,每个数组有 6 个元素:

Random R = new Random(23);列表yValues = new List();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 });}

现在我们将那些虚假的统计数据添加到 BoxPlot 系列中:

S1.ChartType = SeriesChartType.BoxPlot;S1.Points.Clear();for (int i = 0; i 

请注意,每个 DataPoint 都是从 6 个双精度数组创建的!

结果如下:

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

选项 3a:将一些数据系列与 BoxPlot 关联起来,让它自己做数学

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

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

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

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

事实上,您可以查看方框和图表,看看它们是如何完美匹配的.

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

S1.ChartType = SeriesChartType.BoxPlot;S1["BoxPlotSeries"] = "D1;D2;D3;D4;D5;D6";//箱线图绑定!S1.LegendText = "BoxPlot";

我对绑定"使用引号,因为它不是真正的数据绑定;相反,数据系列仅与具有重要属性字符串 "BoxPlotSeries"BoxPlot 系列关联.

您的示例有多个 BoxPlot 系列;此处适用相同的规则.

看看

更新:

您的示例实际上显示了三个箱线图系列;因此颜色,最值得注意的是:集群(即无间隙)显示.

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

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

最后一点:您的示例代码包含一个包含 12 个双精度数和 4 个箱线图系列的数组.这没有任何意义.不过,您可以将 12 个值添加到一个普通系列中,并使用选项 3 将其与一个箱线图系列相关联..

I'm creating manually a boxplot chart. I have 4 double[] arrays with some calculations results that i want show on chart. I don't know how to connect correctly my arrays with chart Series. Here is my chart:

        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);

This is what i get:

As result i want get something like that:

解决方案

You have tried to bind your data to a BoxPlot series. But this has only resulted in binding the first Y-value, which means you have created a set of 'lower whiskers'. All other 5 Y-values are empty, ie are 0. Hence the meager graphics you see..

MSDN: The values for a box are typically calculated values from data that is present in another series. One box symbol (DataPoint object) is associated with one data series.

The data for a Box Plot series may still be populated using data binding, or by employing the Series.Points member (a DataPointCollection object).

Let's look at all of these options:

  1. Use regular data binding. This is what you tried but with a wrong syntax.

  2. You can also add the DataPoints of the box plot series itself one by one with AddY or AddXY, supplying all 6 Y-Values, i.e. feeding in the results of a statistical analysis. Here only one array is used and it contains the six y-values.

  3. Or you can use one or more data series and let the chart summarize those data in one box per series. The series are quite normal, read may be Point, Line or whatever.. They can even be invisible and of course you can use data binding for them.. - Once some data series are in place you can define the BoxPlot series and 'bind' it to the data series by seting its ["BoxPlotSeries"] special property to a string into which you concatenate the Series' Names...

Option 1. Use regular data binding to feed in the stats you have.

This is what you tried. The correct way is a little surprising, though; your data need to be ordered like this:

The outer array (or IEnumerable) must have the six y-values; the six inner arrays should contain one value for each of the data sets you want to show in a box. Let's look at an example with three data sets of faked stats:

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
        };

This is how it looks after binding it to a BoxPlot series S1

S1.Points.DataBindY(yValues);

You can also create individual series; see the update at the bottom for this!

Option 2: Feed in the BoxPlot data yourself

Let's look at an example of the first way: Here we need to have the statistics ready.. First I create a random data structure; it is a List of double arrays each with 6 elements:

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 });
}

Now we add those fake statistics to the BoxPlot series:

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

Note that each DataPoint is created from an array of 6 doubles!

Here is the result:

The chart now shows stats on 8 data sets, all faked ;-)

Option 3a: Associate some data series with the BoxPlot and let it do the math

The other usage is to let the chart to the math: It can calculate the statistics for any number of data series you have and create one box for each.

We will use the same data set as before, but now they are used to create 6 data series, each with 8 points:

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());
}

They are bound to the same numbers as above, but these now have a different meaning. Therefore the results will and should not look alike!!

In fact you can look at the boxes and graphs and see how they nicely fit.

Note the Names I gave the data series; we will need them now, when we 'bind' them to the BoxPlot series:

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

I use quotes for the 'binding' because it isn't real data binding; instead the data series are only associated with the BoxPlot series with the sprecial property string "BoxPlotSeries".

Your example has more than one BoxPlot series; here the same rules apply.

Do have a look at this post which shows another use of BoxPlot including setting individual colors..

Option 3b: Associate some data series with DataPoints you add to the BoxPlot series; here too it will do the math for us

While option 3a seems rather simple I found no way to color the boxes. Here is how we can do that:

First we force the chart to copy the default colors to the series. While we're at it, let's also hide the Legend item:

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

Then we create one DataPoint in out BoxPlot series S1 for each data series; not how my series are ordered: 0=The BoxPlot, 1-6 some data series! You may need to adapt this!

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;
}

Here is the result:

Update:

Your example actually shows three boxplot series; hence the colors and most notably: the clustered (i.e. gapless) display.

This would be a way to bind the above data (from option 1) to three individual boxes:

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);
}

Final note: Your example code contains an array with 12 doubles and also 4 boxplot series. This makes no sense. You can add the 12 values to a normal series and associate it with one boxplot series using option 3, though..

这篇关于如何在 WFA 中将数据添加到 BoxPlot?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆