c # drawing distribution plot

  /// <Summary> 
    /// provide normal image data and 
    /// </ Summary> 
    public class StandardDistribution 
    { 

       
        /// <Summary> 
        /// sample data 
        /// </ Summary> 
        public List <Double > Xs {GET; Private SET;} 

        public StandardDistribution (List <Double> Xs) 
        { 
            this.Xs = Xs; 

            Average = Xs.Average (); 
            Variance = GetVariance (Xs); 

            IF (Variance == 0) the throw new new Exception ( "variance 0"); // this case does not need to count each sample because the data are the same, the interface can prompt accordingly 

            StandardVariance = Math.Sqrt (variance); 
        } 

        /// <Summary> 
        /// variance / the square of the standard deviation
        /// </ Summary> 
        /// </ Summary> 
        // / <param name = "x" > </ param>
        /// <returns></returns>
        Double GET Variance {public; Private SET;} 

        /// <Summary> 
        /// standard deviation 
        /// </ Summary> 
        public Double StandardVariance {GET; Private SET;} 

        /// <Summary> 
        /// arithmetic mean / mathematical expectation 
        /// </ Summary> 
        public Double Average {GET; Private SET;} 

        /// <Summary> 
        ///. 1 / (square root of 2 [pi]) values 
        /// </ Summary> 
        public static Double InverseSqrt2PI = . 1 / Math.Sqrt (2 * Math.PI); 

        /// <Summary> 
        /// Get the specified X value calculation formula Y value is too distributed 
        public Double GetGaussianDistributionY (Double X) 
        {
            double PowOfE = -(Math.Pow(Math.Abs(x - Average), 2) / (2 * Variance));

            double result = (StandardDistribution.InverseSqrt2PI / StandardVariance) * Math.Pow(Math.E, PowOfE);

            return result;
        }

        /// <summary>
        /// 获取正太分布的坐标<x,y>
        /// </summary>
        /// <returns></returns>
        public List<Tuple<double, double>> GetGaussianDistributionYs()
        {
            List<Tuple<double, double>> XYs = new List<Tuple<double, double>>();

            Tuple<double, double> xy = null;

            foreach (double x in Xs)
            {
                = new new Tuple XY <Double, Double> (X, GetGaussianDistributionY (X)); 
                XYs.Add (XY); 
            } 



            return XYS; 
        } 

        /// <Summary> 
        /// Gets a list of integers variance 
        /// </ summary> 
        data list /// <param name = "src" > to calculate the variance of the </ param> 
        /// <Returns> </ Returns> 
        public static Double GetVariance (list <Double> the src) 
        { 
            Double the src = Average. Average (); 
            Double SumOfSquares = 0; 
            src.ForEach (X => {SumOfSquares Math.Pow + = (X - Average, 2);}); 
            return SumOfSquares / src.Count;// variance 
        } 

        /// <Summary> 
        /// Get a list of integers variance 
        /// </ Summary> 
        /// <param name = " src ">To calculate the variance of the data list </ param>
        /// <returns></returns>
        public static float GetVariance(List<float> src)
        {
            float average = src.Average();
            double SumOfSquares = 0;
            src.ForEach(x => { SumOfSquares += Math.Pow(x - average, 2); });
            return (float)SumOfSquares / src.Count;//方差
        }

        /// <summary>
        /// 画学生成绩的正态分布
        /// </summary> 
        /// <param name = "the Width"> </ param> 
        /// <param name = "Height" > </ param>
        /// <param name = "Scores" > fraction, Y value </ param>
        /// <param name="familyName"></param>
        /// <returns></returns>
        public  Bitmap GetGaussianDistributionGraph(int Width, int Height,int TotalScore, string familyName = "宋体") 
            // score abscissa; the value of the normal distribution of the longitudinal axis
        {


            = New new Bitmap Bitmap Bitmap (the Width, the Height); 

            Graphics GDI = Graphics.FromImage (Bitmap); 

            gdi.Clear (Color.White); 
            gdi.SmoothingMode = SmoothingMode.HighQuality; 
            gdi.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; 
            gdi.PixelOffsetMode = PixelOffsetMode.HighQuality; 



            List <Tuple <Double, scores Double >> = GetGaussianDistributionYs () the OrderBy (X => x.Item1) .ToList ();. // Sort convenient connection between the rear dots ensure low score the left 

            float YHeight = 0.8F * Height; // relative to the lower left corner indicating YHeight * 0.9F maxY 
            a float xWidth the Width * = 0.9F; // relative to the lower left corner indicating xWidth * 0.9F maxX 

            a float marginX = (the Width - xWidth) / 2F; // x-axis relative to the left and right edges of pixel image
            float marginY = (Height - YHeight) / 2F; // y-axis pixel images vertically opposite edges 

            of PointF leftTop of PointF new new = (marginX, marginY); 

            of PointF leftBottom of PointF new new = (marginX, marginY YHeight +); // coordinate axis bottom left 


            PointF rightBottom = new PointF (marginX + xWidth, marginY + YHeight); // bottom right axis


 
            gdi.DrawLine (Pens.Gray, leftBottom, rightBottom) ; // x -axis
            gdi.DrawLine (Pens.Gray, leftBottom, leftTop) ; // Y -axis 

            // two arrows four line 6 is also required to coordinate 4 coordinate 

            PointF YArrowLeft = new PointF (leftTop.X - 5, leftTop.Y + 5) ; 
            of PointF YArrowRight of PointF new new = (+ leftTop.X. 5, leftTop.Y +. 5); 
            of PointF XArrowTop of PointF new new = (rightBottom.X -. 5, rightBottom.Y -. 5); 
            of PointF XArrowBottom of PointF new new = (rightBottom.X -. 5 , rightBottom.Y +. 5); 
            gdi.DrawLine (Pens.Gray, rightBottom, XArrowBottom); 
            a float unitX = 0.0F; // X-axis conversion ratio

            gdi.DrawLine (Pens.Gray, leftTop, YArrowLeft); 
            gdi.DrawLine (Pens.Gray, leftTop, YArrowRight); 
            gdi.DrawLine (Pens.Gray, rightBottom, XArrowTop); 

            a float Unity = 0.0F; // convert the Y-axis ratio 

            List <PointF> pointFs = ConvertToPointF ( scores, xWidth * 0.9F, YHeight * 0.9F, leftTop, out unitX, out unitY); // score and probability of converting into coordinates 


            gdi.DrawCurve (Pens.Black, pointFs.ToArray (), 0.0F); // cardinal spline 

            // average parallel to the Y axis 

            of PointF avg_top of PointF new new = (leftTop.X + (a float) * average unitX, leftTop.Y); 
            of PointF avg_bottom of PointF new new = (leftTop. + X-(a float) * Average unitX, leftBottom.Y); 
            gdi.DrawLine (Pens.Black, avg_top, avg_bottom); 
            gdi.DrawString (string.Format ( "{0} ", ((float) Average) .ToString (" F2 ")), new Font (" Arial ", 11), Brushes.Black, avg_bottom.X, avg_bottom.Y-25); 


            // write in the expectation and variance The horizontal axis below the middle

            = New new variance_pf of PointF of PointF (leftBottom.X + (xWidth / 2) -120, avg_bottom.Y + 25); 
            gdi.DrawString (string.Format ( "expected: {0}; variance: {1}", (( float) Average) .ToString ( "F2") , Variance.ToString ( "F2")), new Font ( " Arial",. 11), Brushes.Black, variance_pf.X, variance_pf.Y); 


            


            // the minimum and maximum score fraction 9 is divided into sections marked on the abscissa axis 

            Double Scores.Min = minX (X => x.Item1); 
            Double maxX = Scores.Max (X => x.Item1); 

            Double perSegment = the Totalscore / 10; // (maxX - minX) / 9F; // score for each segment represented by 

            List <double> segs = new List <double> (); // for each segment of the boundary value abscissa 

            segs.Add (leftBottom.X + ( a float) minX * unitX); 

            for (int I =. 1; I <. 11; I ++) 
            {
                segs.Add (leftBottom.X + (a float) unitX minX * + * I * perSegment unitX); 
            } 
            for (int I = 0; I <. 11; I ++) 
            { 
                gdi.DrawPie (Pens.Black, (a float) SEGs [ I] -. 1, leftBottom.Y -. 1, 2, 2, 0, 360); 

                . gdi.DrawString (string.Format ( "{0}", ((+ perSegment * minX (I))) the ToString ( "F0 ")), new Font (" Arial ",. 11), Brushes.Black, (a float) SEGs [I] - 15, leftBottom.Y +. 5); 
            } 




            return Bitmap; 
        } 

        /// <Summary> 
        /// the data into coordinates 
        /// </ Summary> 
        /// <param name = "Scores"> </ param> 
        /// <param name = "X-"> maximum use abscissa </param>
        /// <name = "Y" param > using the longest longitudinal </ param> 
        /// <param name = "leftTop"> origin the upper left corner </ param> 
        /// <Returns> </ Returns> 
        Private static List <of PointF> ConvertToPointF (List <Tuple <Double, Double >> Scores, X-a float, a float the Y, of PointF leftTop, OUT unitX a float, a float Unity OUT) 
        { 
            Double Scores.Max = maxY (X => x.Item2); 
            maxX = Scores.Max Double (X => x.Item1); 

            List <of PointF> = new new Result List <of PointF> (); 

            a float paddingY the Y * = 0.01F; 
            a float * X-paddingX = 0.01F; 

            Unity = (a float) ((Y - paddingY) / maxY ); // units out of the vertical axis represents the calculated desired height ordinate need leftTop.Y + (Y-item2 * unitY ) + paddingY
            unitX = (float) ((X - paddingX) / maxX); // units out of the horizontal axis represents the desired width calculated abscissa ITEM1 * + unitX need leftTop.X 

            of PointF of PointF new new PF = (); 
            the foreach (Tuple < Double, Double> in Item Scores) 
            { 
                PF of PointF new new = (leftTop.X + (a float) item.Item1 * unitX, leftTop.Y + (the Y - (a float) item.Item2 Unity *) + paddingY); 
                result.Add (PF); 
            } 

            return Result; 
        } 

    }

transfer:

            StandardDistribution mathX = new StandardDistribution(scores);
            Bitmap bitmap = mathX.GetGaussianDistributionGraph(800, 480, totalScore);
            bitmap.Save("tt.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

FIG normal test data generation:

Guess you like

Origin www.cnblogs.com/ingstyle/p/11224009.html