예제 #1
0
        public void Test_LinearRegression_RandomXs()
        {
            int    pointCount   = 50;
            double actualSlope  = 3;
            double actualOffset = 200;

            (double[] xs, double[] ys) = GetNoisyLinearData_RandomlySpaced(pointCount, actualSlope, actualOffset);

            // fit the random data with the linear regression model
            var model = new ScottPlot.Statistics.LinearRegressionLine(xs, ys);

            // plot to visually assess goodness of fit
            var plt = new ScottPlot.Plot(450, 300);

            plt.Title($"Y = {model.slope:0.0000}x + {model.offset:0.0}\nR² = {model.rSquared:0.0000}");
            plt.AddScatterPoints(xs, ys);
            // ADD THIS BACK IN!
            //plt.PlotLine(model.slope, model.offset, (xs.Min(), xs.Max()), lineWidth: 2, label: "model", lineStyle: ScottPlot.LineStyle.Dash);
            //plt.PlotLine(actualSlope, actualOffset, (xs.Min(), xs.Max()), lineWidth: 2, label: "actual");
            plt.Legend();
            TestTools.SaveFig(plt);

            // ensure the fit is good
            Assert.AreEqual(actualSlope, model.slope, .5);
            Assert.AreEqual(actualOffset, model.offset, 10);
        }
예제 #2
0
        public void GetCoefficients_FirstXNotZero_ResultEqualtoTI_84_Plus()
        {
            double[] x   = new double[] { 1, 2, 3, 4, 5, 6, 7 };
            double[] y   = new double[] { 2, 2, 3, 3, 3.8, 4.2, 4 };
            var      reg = new ScottPlot.Statistics.LinearRegressionLine(x, y);

            Assert.AreEqual(0.4, reg.slope, 0.0001);
            Assert.AreEqual(1.5428, reg.offset, 0.0001);
        }
예제 #3
0
        public void ExecuteRecipe(Plot plt)
        {
            // Create some linear but noisy data
            double[] ys = DataGen.NoisyLinear(null, pointCount: 100, noise: 30);
            double[] xs = DataGen.Consecutive(ys.Length);
            double   x1 = xs[0];
            double   x2 = xs[xs.Length - 1];

            // use the linear regression fitter to fit these data
            var model = new ScottPlot.Statistics.LinearRegressionLine(xs, ys);

            // plot the original data and add the regression line
            plt.Title($"Y = {model.slope:0.0000}x + {model.offset:0.0}\nR² = {model.rSquared:0.0000}");
            plt.AddScatter(xs, ys, lineWidth: 0);
            plt.AddLine(model.slope, model.offset, (x1, x2), lineWidth: 2);
        }
예제 #4
0
        private void CreateScatterAndFitRegression()
        {
            Random rand = new Random();

            // generate linear data with noise
            double slope      = rand.Next(-1000, 1000) / 100.0;
            double offset     = rand.Next(-1000, 1000);
            int    pointCount = rand.Next(50, 1000);

            double[] ys = ScottPlot.DataGen.NoisyLinear(
                rand: rand,
                pointCount: pointCount,
                slope: slope,
                offset: offset,
                noise: rand.Next(10, 500)
                );

            // create matching X-axis ticks
            double pointSpacing = rand.Next(1, 1000) / 1000.0;

            double[] xs = ScottPlot.DataGen.Consecutive(ys.Length, spacing: pointSpacing);
            realLineLabel.Text = string.Format("Y = {0:0.00}x + {1:0.00} (n={2})", slope / pointSpacing, offset, pointCount);

            // plot data
            formsPlot1.plt.Clear();
            formsPlot1.plt.PlotScatter(xs, ys, lineWidth: 0);
            formsPlot1.plt.AxisAuto();

            // perform the linear regression
            var    linreg      = new ScottPlot.Statistics.LinearRegressionLine(xs, ys);
            double fittedSlope = linreg.slope;

            fittedLineLabel.Text = string.Format("Y = {0:0.00}x + {1:0.00}", fittedSlope, linreg.offset);

            // plot the linear regression line (as a scatter plot with just two points)
            double x1 = xs.First();
            double x2 = xs.Last();
            double y1 = linreg.GetValueAt(xs.First());
            double y2 = linreg.GetValueAt(xs.Last());

            formsPlot1.plt.PlotLine(x1, y1, x2, y2, lineWidth: 3, color: Color.Black);

            // force a redraw of the user control
            formsPlot1.Render();
        }
예제 #5
0
        public void Test_LinearRegression_EvenlySpacedXs()
        {
            Random rand = new Random(0);

            for (int i = 0; i < 1000; i++)
            {
                // create random data
                (double slope, double offset, double[] xs, double[] data) = GetRandomRegressionData(rand);


                // fit the random data with the linear regression model
                var model = new ScottPlot.Statistics.LinearRegressionLine(data, 0, 1);

                // ensure the model's coeffecients are similar to the real ones
                double slopeError  = Math.Abs(slope - model.slope);
                double offsetError = Math.Abs(offset - model.offset);
                Assert.That(slopeError, Is.LessThan(.1));
                Assert.That(offsetError, Is.LessThan(10));
            }
        }
예제 #6
0
            public void Render(Plot plt)
            {
                // Create some linear but noisy data
                Random rand = new Random(0);

                double[] ys = ScottPlot.DataGen.NoisyLinear(rand, pointCount: 100, noise: 30);
                double[] xs = ScottPlot.DataGen.Consecutive(ys.Length);
                double   x1 = xs[0];
                double   x2 = xs[xs.Length - 1];

                // use the linear regression fitter to fit these data
                var    model = new ScottPlot.Statistics.LinearRegressionLine(xs, ys);
                double y1    = model.GetValueAt(x1);
                double y2    = model.GetValueAt(x2);

                // plot the original data and add the regression line
                plt.PlotScatter(xs, ys, lineWidth: 0, label: "original data");
                plt.PlotLine(x1, y1, x2, y2, lineWidth: 3, label: "linear regression");
                plt.Legend();
                plt.Title(model.ToString());
            }
예제 #7
0
        private void formsPlot1_Load(object sender, EventArgs e)
        {
            // this is the plotting place - all in the Load

            //           string tname1 = "WXROVER";
            //           string tname2 = "WXIN";
            //           int pointcount = 5000;
            //           double[,] tempData;

            int cnt = 0;
            //            double[] t1 = new double[Globals.pointcount];
            //            double[] t2 = new double[Globals.pointcount];

            // a couple of local lists
            List <double> orgs = new List <double> {
            };
            List <double> chks = new List <double> {
            };



            classWXstnChk WXchk = new classWXstnChk();                                                         //make an object WXck

            WXchk.cnxstring("192.168.1.15", "DAWES_SQL2008", "WeatherStation", "WeatherStation", "Esp32a.b."); //a constructor - no arguments

            //go get the data
            Globals.tempData = WXchk.getTemperatureData(Globals.pointcount, Globals.tname1, Globals.tname2);  //this gets the data as an XY pair
                                                                                                              //there will be a lot of duplcates in this array.  Lets remove the dupes - done in the SQL



            //for scotterplot to work, these need to be in two separate Arrays, so we seperate them out in
            //this loop and we might as well get rid of the empty slots
            //maybe this would also work
            // double [] tab1 = new double[tempData.Length];

            for (int i = 0; i < pointcount - 1; i++)
            {
                if (Globals.tempData[i, 0] > 0)
                {
                    t1[i]   = tempData[i, 0];
                    t2[i]   = tempData[i, 1];
                    t1qq[i] = tempData[i, 0];
                    t2qq[i] = tempData[i, 1];

                    //might as well put the data in the grid
                    dgXY.Rows.Add();
                    try
                    {
                        dgXY.Rows[i].Cells["dgXYrecord"].Value = i.ToString(); //puts the record no on the dgXY
                        dgXY.Rows[i].Cells["dgXYx"].Value      = t1[i];
                        dgXY.Rows[i].Cells["dgXYy"].Value      = t2[i];
                    }
                    catch { }

                    cnt += 1;
                }
            }//end of for loop

            // we have two arrays lets sort them to form a QQ plot
            Array.Sort(t1qq);
            Array.Sort(t2qq);



            // the arrays are declared a certain size and are now full of 0's
            //this will reduce them down to just data.
            // if there is no data in the arrays then cnt will = 0
            if (cnt == 0)
            {
                MessageBox.Show("No Data in your selection.", "No data", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }


            Array.Resize(ref t1, cnt);
            Array.Resize(ref t2, cnt);
            cntG = cnt;

            // int aa = cnt;
            int ab = t2.GetLength(0);
            // create a Population object from the data
            var popt1 = new ScottPlot.Statistics.Population(t1);
            var popt2 = new ScottPlot.Statistics.Population(t2);

            // now lets fill the stats box
            lblT1.Text       = tname1;
            lblT2.Text       = tname2;
            lblMeanT1.Text   = Math.Round(popt1.mean, 2).ToString();
            lblMeanT2.Text   = Math.Round(popt2.mean, 2).ToString();
            lblMedT1.Text    = Math.Round(popt1.median, 2).ToString();
            lblMedT2.Text    = Math.Round(popt2.median, 2).ToString();
            lblQ3T1.Text     = popt1.Q3.ToString();
            lblq3table2.Text = popt1.Q3.ToString();
            lblQ1t1.Text     = popt1.Q1.ToString();
            lblQ1T2.Text     = popt2.Q1.ToString();
            lblstderrT1.Text = Math.Round(popt1.stdErr, 2).ToString();
            lblstderrT2.Text = Math.Round(popt2.stdErr, 2).ToString();
            lblstdevT1.Text  = Math.Round(popt1.stDev, 2).ToString();
            lblstdevT2.Text  = Math.Round(popt2.stDev, 2).ToString();
            lblIQRt1.Text    = Math.Round(popt1.IQR, 2).ToString();
            lblIQRt2.Text    = Math.Round(popt2.IQR, 2).ToString();
            lblNtn1.Text     = cnt.ToString(); //opt1.aa.ToString();
                                               // lblNtn2.Text = ab.ToString(); // popt2.count.ToString();


            //this gives us the regression line and the correlation coeficient
            var    model = new ScottPlot.Statistics.LinearRegressionLine(t1, t2);
            string line  = $"Y={model.slope:0.0000}X + {model.offset:0.0}";

            lblLine.Text   = line;
            lblCorrel.Text = $"R² = {model.rSquared:0.0000}";

            formsPlot1.plt.Title($"ScarpWeather Temperature XY Plot");
            formsPlot1.plt.XLabel(tname1);
            formsPlot1.plt.YLabel(tname2);
            //formsPlot1.plt.AxisAuto(horizontalMargin: 0, verticalMargin: 0.5);
            //                 xmin,xmax,ymin,ymax

            int axisMin, axisMax;

            axisMin = (int)popt1.min - 2;  //get some data from the arrays
            //axisMin = 0;
            axisMax = (int)popt1.max + 2;

            formsPlot1.plt.Axis(axisMin, axisMax, axisMin, axisMax); //defines the min and max of the chart
                                                                     //            formsPlot1.plt.Axis(15,40,15,40);


            formsPlot1.plt.Legend();  // got ot have this be we toggle it with hte context menu

            //this draws the scatter plot
            XYplotPoints = formsPlot1.plt.PlotScatter(t1, t2, Color.DarkCyan, lineWidth: 0, markerSize: 5, label: "XYData");
            //draw the QQ plot
            QQplotPoints         = formsPlot1.plt.PlotScatter(t1qq, t2qq, Color.DarkGreen, lineWidth: 0, markerSize: 5, label: "QQData");
            QQplotPoints.visible = false;

            // draws the regresion line
            //if (plotRegression)
            regLine = formsPlot1.plt.PlotLine(model.slope, model.offset, (axisMin, axisMax), lineWidth: 2, label: "Regression", color: Color.BlueViolet);

            //plot a 45 degree line = X=Y
            XequalsYLine = formsPlot1.plt.PlotLine(1.0, 0.0, (0, 100), Color.Goldenrod, lineWidth: 2, label: "X=Y", lineStyle: ScottPlot.LineStyle.Dot); //uses the equation of the line to plot

            //the 10% error lines
            errorLineA = formsPlot1.plt.PlotLine(0, 0, 100.0 - 0.1 * 100, 100, color: Color.OrangeRed, lineWidth: 2, label: "10%error", lineStyle: ScottPlot.LineStyle.Dash);
            errorLineB = formsPlot1.plt.PlotLine(0, 0, 100, 100.0 - 0.1 * 100, color: Color.OrangeRed, lineWidth: 2, lineStyle: ScottPlot.LineStyle.Dash);

            formsPlot1.Render();//draw the chart on the PC screen
        }//end function
예제 #8
0
        public void RenderPlot()
        {
            plotFrame.plt.Clear();
            RefreshTitleAndAxis(false);
            bool containsDateAxis = false;

            foreach (PlotParameters curr in ((App)App.Current).GetSeries())
            {
                if (curr.drawSettings.label == "")
                {
                    curr.drawSettings.label = null;//Prevents it from showing up in the legend
                }

                if (curr.drawSettings.dateXAxis)
                {
                    containsDateAxis = true;
                    object timeUnit;
                    object numTimeUnitsObj;
                    curr.metaData.TryGetValue("timeUnit", out timeUnit);
                    curr.metaData.TryGetValue("numTimeUnits", out numTimeUnitsObj);
                    ScottPlot.Config.DateTimeUnit dateTimeUnit = (ScottPlot.Config.DateTimeUnit)timeUnit;
                    int numTimeUnits = (int)numTimeUnitsObj;

                    dateUnit        = dateTimeUnit;
                    dateUnitSpacing = numTimeUnits;

                    if (dateTimeUnit == ScottPlot.Config.DateTimeUnit.Year)//Grid spacing of one year is currently unsupported -_-
                    {
                        plotFrame.plt.Grid(xSpacing: 12, xSpacingDateTimeUnit: ScottPlot.Config.DateTimeUnit.Month);
                    }
                    else
                    {
                        plotFrame.plt.Grid(xSpacing: numTimeUnits, xSpacingDateTimeUnit: dateTimeUnit);
                    }
                    plotFrame.plt.Ticks(dateTimeX: true, xTickRotation: 30, fontSize: 10); // Default fontSize is 12
                }

                switch (curr.drawSettings.type)
                {
                case PlotType.scatter:
                    double[] xsScatter = ((double[][])curr.data)[0];
                    double[] ysScatter = ((double[][])curr.data)[1];
                    if (logAxis)
                    {
                        ysScatter = ScottPlot.Tools.Log10(ysScatter);
                    }

                    if (!curr.hasErrorData)
                    {
                        plotFrame.plt.PlotScatterHighlight(xsScatter, ysScatter, curr.drawSettings.colour, curr.drawSettings.drawLine ? 1 : 0, label: curr.drawSettings.label, markerShape: curr.drawSettings.markerShape, highlightedColor: curr.drawSettings.colour);
                    }
                    else
                    {
                        double[] errorX = ((double[][])curr.errorData)[0];
                        double[] errorY = ((double[][])curr.errorData)[1];
                        plotFrame.plt.PlotScatterHighlight(xsScatter, ysScatter, curr.drawSettings.colour, curr.drawSettings.drawLine ? 1 : 0, label: curr.drawSettings.label, markerShape: curr.drawSettings.markerShape, errorX: errorX, errorY: errorY, highlightedColor: curr.drawSettings.colour);
                    }

                    if (curr.drawSettings.drawLinearRegression)
                    {
                        var    model = new ScottPlot.Statistics.LinearRegressionLine(xsScatter, ysScatter);
                        double x1    = xsScatter[0];
                        double x2    = xsScatter[xsScatter.Length - 1];
                        double y1    = model.GetValueAt(x1);
                        double y2    = model.GetValueAt(x2);
                        plotFrame.plt.PlotLine(x1, y1, x2, y2, lineWidth: 3, label: $"ŷ = {model.offset:f9} + {model.slope:f9}x");
                    }
                    break;

                case PlotType.signal:
                    object sampleRate = 100;
                    curr.metaData.TryGetValue("sampleRate", out sampleRate);
                    object xOffset = 0;
                    curr.metaData.TryGetValue("xOffset", out xOffset);
                    double[] data = (double[])curr.data;

                    if (logAxis)
                    {
                        data = ScottPlot.Tools.Log10(data);
                    }
                    plotFrame.plt.PlotSignalConst(data, (double)sampleRate, (double)xOffset, color: curr.drawSettings.colour, lineWidth: curr.drawSettings.drawLine ? 1 : 0, label: curr.drawSettings.label, markerSize: 0);
                    break;

                case PlotType.bar:
                    double[] xsBar = ((double[][])curr.data)[0];
                    double[] ysBar = ((double[][])curr.data)[1];
                    if (logAxis)
                    {
                        ysBar = ScottPlot.Tools.Log10(ysBar);
                    }
                    if (!curr.hasErrorData)
                    {
                        plotFrame.plt.PlotBar(xsBar, ysBar, fillColor: curr.drawSettings.colour, outlineColor: curr.drawSettings.colour, errorColor: curr.drawSettings.colour, label: curr.drawSettings.label);
                    }
                    else
                    {
                        double[] errorY = ((double[])curr.errorData);
                        plotFrame.plt.PlotBar(xsBar, ysBar, fillColor: curr.drawSettings.colour, outlineColor: curr.drawSettings.colour, errorColor: curr.drawSettings.colour, label: curr.drawSettings.label, errorY: errorY);
                    }
                    break;

                case PlotType.histogram:
                    ScottPlot.Statistics.Histogram histogram = new ScottPlot.Statistics.Histogram((double[])curr.data);
                    double[] yData = histogram.counts;

                    switch (curr.drawSettings.histogramType)
                    {
                    case HistogramType.fraction | HistogramType.density:
                        yData = histogram.countsFrac;
                        break;

                    case HistogramType.fraction | HistogramType.cumulative:
                        yData = histogram.cumulativeFrac;
                        break;

                    case HistogramType.count | HistogramType.cumulative:
                        yData = histogram.cumulativeCounts;
                        break;
                    }


                    plotFrame.plt.PlotBar(histogram.bins, yData, fillColor: curr.drawSettings.colour, outlineColor: curr.drawSettings.colour, errorColor: curr.drawSettings.colour, label: curr.drawSettings.label);
                    break;

                case PlotType.horizontal_line:
                    double hLineData = (double)curr.data;
                    plotFrame.plt.PlotHLine(hLineData, color: curr.drawSettings.colour, label: curr.drawSettings.label);
                    break;

                case PlotType.vertical_line:
                    double vLineData = (double)curr.data;
                    plotFrame.plt.PlotVLine(vLineData, color: curr.drawSettings.colour, label: curr.drawSettings.label);
                    break;

                case PlotType.horizontal_span:
                    (double hSpanMin, double hSpanMax) = (ValueTuple <double, double>)curr.data;
                    plotFrame.plt.PlotHSpan(hSpanMin, hSpanMax, color: curr.drawSettings.colour, label: curr.drawSettings.label);
                    break;

                case PlotType.vertical_span:
                    (double vSpanMin, double vSpanMax) = (ValueTuple <double, double>)curr.data;
                    plotFrame.plt.PlotVSpan(vSpanMin, vSpanMax, color: curr.drawSettings.colour, label: curr.drawSettings.label);
                    break;

                case PlotType.box_whisker:
                    var plotObj = plotFrame.plt.PlotPopulations((ScottPlot.Statistics.Population)curr.data, label: curr.drawSettings.label);
                    plotObj.boxStyle = PlottablePopulations.BoxStyle.BoxMedianQuartileOutlier;
                    plotObj.displayDistributionCurve = false;
                    break;

                case PlotType.function:
                    var f = (Func <double, double?>)curr.data;
                    plotFrame.plt.PlotFunction(f, label: curr.drawSettings.label, markerShape: MarkerShape.none, lineStyle: LineStyle.Dash);
                    break;

                case PlotType.bar_grouped:
                    var      plotData     = ((double[][])curr.data);
                    string[] groupLabels  = (string[])curr.metaData.GetValueOrDefault("group_names");
                    string[] seriesLabels = (string[])curr.metaData.GetValueOrDefault("series_names");
                    if (!curr.hasErrorData)
                    {
                        plotFrame.plt.PlotBarGroups(groupLabels, seriesLabels, plotData);
                    }
                    else
                    {
                        plotFrame.plt.PlotBarGroups(groupLabels, seriesLabels, plotData, (double[][])curr.errorData);
                    }
                    break;
                }
            }

            isDateAxis = containsDateAxis;
            plotFrame.plt.Legend();

            (double highlightX, double highlightY) = (plotFrame.plt.Axis()[0], plotFrame.plt.Axis()[3]);

            foreach (var curr in rawPlottables)
            {
                if (curr != snappedCoordinates || showCoordinates)
                {
                    plotFrame.plt.Add(curr);//Got axed when we cleared everything
                }
            }

            RenderFrame();
        }