从图表中的文件生成趋势线

我希望能够从文件夹中获取.csv文件并将其绘制在图表中。

目前,我只是保存文件并显示如下的单个曲线:

RunTest函数:

 public List<Tuple> runTest() { _dpg = new Root(this, "english", false); _dpg.Init(); var filename = "Dpg10Export_" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".csv"; List<Tuple> results = new List<Tuple>(); var measurement = new Measurement(); var resultCode = RunMeasurement(60, 1000, 2200, ref measurement, null /* TODO: ref ProgressBar? */); using (var fileStream = new StreamWriter(filename)) { var count = measurement.I_inc_Values.Count; for (var i = 0; i < count; i++) { var item = measurement.I_inc_Values[i + 1]; var current = (float)Convert.ToDouble(item); item = measurement.LI_inc_Values[i + 1]; var inductance = (float)Convert.ToDouble(item); var line = current.ToString() + ";" + inductance.ToString() + ";"; fileStream.WriteLine(line); currentList.Add(current); inductanceList.Add(inductance); results.Add(new Tuple(current,inductance)); if (i == 0 || (i + 1) % 32 == 0) { Console.WriteLine((i + 1) + ": " + line); } } } return results; } 

此代码生成一个类似于以下内容的csv文件:

0,22 | 0,44

0,32 | 0,54

0,44 | 0,65

这些值产生的曲线如下所示:

图片

单击“获取波形”按钮时,将生成上面的曲线。 但是,我想显示已生成的所有曲线,以及趋势线 。 我怎么做到这一点?

 void BindData(List<Tuple> results) { chart.Series.Clear(); var series1 = new System.Windows.Forms.DataVisualization.Charting.Series { Name = "curr/induc", Color = System.Drawing.Color.Green, IsVisibleInLegend = true, IsXValueIndexed = true, ChartType = SeriesChartType.Line }; foreach (var i in results) { series1.Points.AddXY(i.Item2,i.Item1); } chart.Invalidate(); chart.Series.Add(series1); } private void getWaveformBtn_Click(object sender, EventArgs e) { Dpg10Client.Dpg10Settings settings = new Dpg10Client.Dpg10Settings(); Dpg10Instrument hej = new Dpg10Instrument(settings); List<Tuple> results = hej.runTest(); double current, inductance; foreach(var i in results) { current = i.Item1; inductance = i.Item2; textBoxWaveformInput.Text += current.ToString() + inductance.ToString(); } BindData(results); } 

TL; DR

解析CSV文件中的信息以生成曲线,并基于这些文件创建趋势线。

标记为重复:该答案是关于直线的,这些值可以在曲线中波动。

有很多方法可以解决您问题中的大多数问题。

让我只解决与计算多个系列平均值有关的实际问题,即不处理使用CSV文件中的数据创建系列。

有一个内置的类可以做各种高级数学,包括财务和统计 ,但我没有找到一个有助于创建一个以上系列的平均线/曲线。

所以让我们自己做吧..

第一个问题是,为了计算平均值,我们不仅需要数据,而且数据(即它们的x值)必须分组“箱” ,我们希望从中获得平均值。

除非数据已经按这样分组,例如因为每天每个系列有一个值,我们需要创建这样的组。

让我们先收集我们想要处理的所有系列中的所有积分; 你可能需要调整循环以包括你的系列..:

 var allPoints = new List (); for (int s = 0; s < 3; s++) // I know I have created these three series { Series ser = chartGraphic.Series["S" + (s+1)]; allPoints.AddRange(ser.Points); } 

接下来,我们需要确定一个bin范围/大小,这是一个确定哪些x值应落入同一个bin / group的值。 我选择了10箱。

所以我们最好得到x值的总范围并除以我们想要的箱数...:

 double xmax = allPoints.Max(x => x.XValue); double xmin = allPoints.Min(x => x.XValue); int bins = 10; double groupSize = (xmax - xmin) / (bins - 1); 

接下来我们做实际数学; 为此,我们订购我们的积分,对它们进行分组并选择每个分组的平均值 。:

 var grouped = allPoints .OrderBy(x => x.XValue) .GroupBy(x => groupSize * (int)(x.XValue /groupSize )) .Select(x => new { xval = x.Key, yavg = x.Average(y => y.YValues[0]) }) .ToList(); 

现在我们可以将它们添加到新系列中以显示分档中的平均值:

  foreach (var kv in grouped) avgSeries.Points.AddXY(kv.xval + groupSize/2f, kv.yavg); 

我将平均点放在箱子中心。

这是一个例子:

在此处输入图像描述

关于这个例子的几点说明:

平均线没有显示真正的“趋势”,因为我的数据几乎是随机的。

我已经将Markers添加到所有系列中,以使DataPoints脱颖而出。 这是我为平均系列做的方式:

 avgSeries.MarkerStyle = MarkerStyle.Cross; avgSeries.MarkerSize = 7; avgSeries.BorderWidth = 2; 

我添加了一个StripLine来显示垃圾箱。 方法如下:

 StripLine sl = new StripLine(); sl.BackColor = Color.FromArgb(44,155,155,222); sl.StripWidth = groupSize; sl.Interval = groupSize * 2; sl.IntervalOffset = chartGraphic.ChartAreas[0].AxisX.IntervalOffset; chartGraphic.ChartAreas[0].AxisX.StripLines.Add(sl); 

我还设置了一个值为-300的非常低值,以certificate它将如何降低其箱中的平均值。 为了使图表仍然很好地以正常的数据范围为中心,我将一个ScaleBreakStyle添加到y轴:

 chartGraphic.ChartAreas[0].AxisY.ScaleBreakStyle.BreakLineStyle = BreakLineStyle.Wave; chartGraphic.ChartAreas[0].AxisY.ScaleBreakStyle.Enabled = true;