Interpolation in MS Chart

I need to implement interpolation and extrapolation in Ms-Chart in a Windows application.

For interpolation, I use the MathNet library. but still I donโ€™t know how to implement this.

I am trying to implement Interpolation as shown below.

using MathNet.Numerics.Interpolation.Algorithms; NevillePolynomialInterpolation objIterpolate = new NevillePolynomialInterpolation(Xpoints, Ypoints); double NewYValue; NewYValue = Math.Abs(objIterpolate.Interpolate(newValue); 

I am migrating to XPoints in NevillePolynomialInterpolation() as the first parameter, which is an XValues โ€‹โ€‹array of my chart. and Ypoints as an array of YValues โ€‹โ€‹of my chart.

I pass newValue as the XV value to get the interpolated value.

Can anyone suggest whether this is correct or suggest the right way to implement interpolation.

+7
source share
1 answer

I managed to create a short example, so let me know if my code, which I pasted below, will be for you.

I'm really not used to the MathDotNet library, however, the XML documentation is pretty good, so the learning curve is actually not a cool one, just one .NET library among many others.

Otherwise, you can still go to the library website to look at your documentation, except for a few examples that I'm not sure about the interpolation coverage, you will probably find the same thing that you got by reading the XML documentation, you also can check out github and see the interpolation implementation you want to handle.

Of course, you can also try to implement from scratch if you stick to the algorithm described here: http://en.wikipedia.org/wiki/Neville%27s_algorithm

In any case, I suggested that you want to use the MathDotNet library to perform Neville polynomial interpolation and display raw and interpolated data in the same area of โ€‹โ€‹the diagram.

More information can be found here (still don't expect this):

About the MS diagram, all about how to deal with any other Winforms Control, just check the documentation, if there is something complicated, indicate that it is difficult for you, and I will try to explain to you.

Until now, and to be honest, Iโ€™m struggling a bit with what you donโ€™t understand, is it MS Chart, MathDotNet, and both? Which one is the problem for you?

In any case, there is nothing really fantastic, just passing your X and Y Points to the MathDotNet library (as long as the base Xs and Ys implement IEnumerable<T> , like T[] arrays, that's fine)

Then the library performs all the mathematical calculations for you, and you just need to use the Interpolate(...) methods of the given interpolation (you should understand that Interpolation here means a kind of interpolation mechanism, sort of).

I assumed that in your code snippet: XPoints and YPoints are collections of IEnumerable<T> (since you mentioned that they are arrays), where T is a Double , Single or any other type of .NET Number Primitive that suits you well .

 // Copyright: Nothing At All License using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using MathNet.Numerics.Random; namespace HelpSO { public static class Program { [STAThread] public static void Main(params String[] arguments) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var mainForm = new MainForm(); Application.Run(mainForm); } } /// <summary> /// Main Form. /// </summary> public class MainForm : Form { /// <summary> /// Initializes the chart and cosmetics, make-up, glamour, etc.. /// </summary> /// <returns>The chart.</returns> private static Chart InitializeChart() { var chart = new Chart() { Dock = DockStyle.Fill, }; const String defaultChartAreaName = @"Default"; const String defaultLegendName = @"Default"; const String defaultTitleName = @"Default"; var chartArea = chart.ChartAreas.Add(defaultChartAreaName); var labelFont = new Font(@"Tahoma", 8f); var axisX = chartArea.AxisX; var axisY = chartArea.AxisY; axisX.Title = @"X"; axisY.Title = @"Y"; axisX.LabelStyle.Format = axisX.LabelStyle.Format = "F4"; axisX.TitleFont = axisY.TitleFont = labelFont; axisX.LabelStyle.Font = axisY.LabelStyle.Font = labelFont; axisX.TitleAlignment = axisY.TitleAlignment = StringAlignment.Far; axisX.MajorGrid.Enabled = axisY.MajorGrid.Enabled = true; axisX.MinorGrid.Enabled = axisY.MinorGrid.Enabled = true; axisX.MinorGrid.LineDashStyle = axisY.MinorGrid.LineDashStyle = ChartDashStyle.Dash; axisX.MinorGrid.LineColor = axisY.MinorGrid.LineColor = Color.Gainsboro; var legend = chart.Legends.Add(defaultLegendName); legend.TitleSeparator = LegendSeparatorStyle.ThickGradientLine; legend.BorderColor = Color.Black; legend.Title = "Legend"; var title = chart.Titles.Add(defaultTitleName); title.Text = @"My Awesome interpolated data"; title.Font = new Font(title.Font.FontFamily, 12f); MainForm.InitializeChartSeries(chart); return chart; } /// <summary> /// Initializes the chart series and related data (raw and interpolated). /// </summary> /// <param name="chart">Chart.</param> private static void InitializeChartSeries(Chart chart) { const String rawDataSeriesName = @"Raw Data"; const String interpolatedDataSeriesName = @"Interpolated Data"; var rawDataSeries = chart.Series.Add(rawDataSeriesName); var interpolatedDataSeriesSeries = chart.Series.Add(interpolatedDataSeriesName); rawDataSeries.ChartType = SeriesChartType.FastLine; interpolatedDataSeriesSeries.ChartType = SeriesChartType.Spline; rawDataSeries.BorderWidth = interpolatedDataSeriesSeries.BorderWidth = 2; var rawDataPoints = DataFactory.GenerateDummySine(10, 1, 0.25); var interpolatedDataPoints = DataFactory.Interpolate(rawDataPoints, 10); rawDataSeries.Points.DataBind(rawDataPoints, @"X", @"Y", String.Empty); interpolatedDataSeriesSeries.Points.DataBind(interpolatedDataPoints, @"X", @"Y", String.Empty); } /// <summary> /// Initializes a new instance of the <see cref="HelpSO.MainForm"/> class. /// </summary> public MainForm() { this.StartPosition = FormStartPosition.CenterScreen; var chart = MainForm.InitializeChart(); this.Controls.Add(chart); } } /// <summary> /// Data Factory. /// </summary> public static class DataFactory { /// <summary> /// Generates a dummy sine. /// </summary> /// <returns>The dummy sine.</returns> /// <param name="count">Count.</param> /// <param name="amplitude">Amplitude.</param> /// <param name="noiseAmplitude">Noise amplitude.</param> public static IList<Point2D<Double, Double>> GenerateDummySine(UInt16 count, Double amplitude, Double noiseAmplitude) { if (count < 2) { throw new ArgumentOutOfRangeException(@"count"); } else { var dummySinePoints = new List<Point2D<Double, Double>>(); var random = new Random(); var xStep = 1.0 / count; for (var x = 0.0; x < 1.0; x += xStep) { var y = amplitude * Math.Sin(2f * Math.PI * x) + random.NextDouble() * noiseAmplitude; var dummySinePoint = new Point2D<Double, Double>(x, y); dummySinePoints.Add(dummySinePoint); } return dummySinePoints; } } /// <summary> /// Interpolate the specified source. /// </summary> /// <param name="source">Source.</param> /// <param name="countRatio">Count ratio.</param> public static IList<Point2D<Double, Double>> Interpolate(IList<Point2D<Double, Double>> source, UInt16 countRatio) { if (countRatio == 0) { throw new ArgumentOutOfRangeException(@"countRatio"); } else if (source.Count < 2) { throw new ArgumentOutOfRangeException(@"source"); } else { var rawDataPointsX = source.Select(item => item.X); var rawDataPointsY = source.Select(item => item.Y); // Could be done within one loop only... so far I'm pretty busy will update that example later var xMin = rawDataPointsX.Min(); var xMax = rawDataPointsX.Max(); // Different Kinds of interpolation here... it all up to you o pick up the one that gonna match your own situation // var interpolation = MathNet.Numerics.Interpolation.NevillePolynomialInterpolation.Interpolate(rawDataPointsX, rawDataPointsY); var interpolation = MathNet.Numerics.Interpolation.CubicSpline.InterpolateNatural(rawDataPointsX, rawDataPointsY); var listCopy = source.ToList(); var xStep = (xMax - xMin) / (source.Count * countRatio); for (var x = xMin; x <= xMax; x += xStep) { var y = interpolation.Interpolate(x); var point2D = new Point2D<Double, Double>(x, y); listCopy.Add(point2D); } return listCopy; } } } // C# lacks, for ***now***, generic constraints for primitive "numbers" public struct Point2D<TX, TY> where TX : struct, IComparable, IFormattable, IConvertible, IComparable<TX>, IEquatable<TX> where TY : struct, IComparable, IFormattable, IConvertible, IComparable<TY>, IEquatable<TY> { public static Point2D<TX, TY> Empty = new Point2D<TX, TY>(); public Point2D(TX x, TY y) { this._x = x; this._y = y; } // C# 6 I miss you here: sad private readonly TY _y; public TY Y { get { return this._y; } } // and there too :-( private readonly TX _x; public TX X { get { return this._x; } } } } 

Feel free to ask more questions about this.

0
source

All Articles