A normal distribution is a probability distribution that occurs arise when you analyze seemingly “random” occurrences. You can define a normal distribution in terms of its mean and standard deviation.

- Mean (μ)
- This is the basically the average of the values in the data set.
- Standard deviation (σ)
- This is a measurement of how tall and peaked or short and wide the curve it.

Its is also helpful to define the curve’s variance, which is simply σ^{2}. With those three values defined, you can graph a normal distribution by using the following equation.

The notation F(x|μ,σ) means you’re calculating a function of x given fixed values for μ and σ.

The following code shows the function used by the example.

// The normal distribution function. private float F(float x, float one_over_2pi, float mean, float stddev, float var) { return (float)(one_over_2pi * Math.Exp(-(x - mean) * (x - mean) / (2 * var))); }

This is simply a matter of plugging in the values for x, the mean, the standard deviation, and the variance.

That’s all there is to the example as far as calculating the distribution function is concerned. Most of the example’s code deals with drawing it. The code is fairly long so it’s presented in pieces below.

The following code shows how the program starts drawing the curve.

private void btnDraw_Click(object sender, EventArgs e) { float mean = float.Parse(txtMean.Text); float stddev = float.Parse(txtStdDev.Text); float var = stddev * stddev; // Make a bitmap. Bitmap bm = new Bitmap( picGraph.ClientSize.Width, picGraph.ClientSize.Height); using (Graphics gr = Graphics.FromImage(bm)) { gr.SmoothingMode = SmoothingMode.AntiAlias; // Define the mapping from world // coordinates onto the PictureBox. const float wxmin = -5.1f; const float wymin = -0.2f; const float wxmax = -wxmin; const float wymax = 1.1f; const float wwid = wxmax - wxmin; const float whgt = wymax - wymin; RectangleF world = new RectangleF(wxmin, wymin, wwid, whgt); PointF[] device_points = { new PointF(0, picGraph.ClientSize.Height), new PointF(picGraph.ClientSize.Width, picGraph.ClientSize.Height), new PointF(0, 0), }; Matrix transform = new Matrix(world, device_points);

This code gets the mean and standard deviation entered by the user. It calculates the variance.

Next the code creates a `Bitmap` to hold the drawing. It makes an associated `Graphics` object to do the drawing.

To make drawing easier, the program will draw in a coordinate system that’s natural for it, so the code defines constants to represent the world coordinates where it will draw. For this example, I used -5.1 ≤ x ≤ 5.1, -0.2 ≤ y ≤ 1.1. Those values work well for distributions with means near 0 and relatively small standard deviations.

Next the code creates a `RectangleF` defining the world coordinates and an array if `PointF` that indicates where the upper left, upper right, and lower left corners of the world coordinates should be mapped to fit on the `Graphics` object that will be used for drawing. It uses the `RectangleF` and array if `PointF` to make a `Matrix` representing a transformation from world coordinates onto a `Graphics` object. You’ll see how that’s used shortly.

The following code shows the next few steps.

// Make a thin Pen to use. using (Pen pen = new Pen(Color.Red, 0)) { using (Font font = new Font("Arial", 8)) { // Draw the X axis. gr.Transform = transform; pen.Color = Color.Black; gr.DrawLine(pen, wxmin, 0, wxmax, 0); for (int x = (int)wxmin; x <= wxmax; x++) { gr.DrawLine(pen, x, -0.05f, x, 0.05f); gr.DrawLine(pen, x + 0.25f, -0.025f, x + 0.25f, 0.025f); gr.DrawLine(pen, x + 0.50f, -0.025f, x + 0.50f, 0.025f); gr.DrawLine(pen, x + 0.75f, -0.025f, x + 0.75f, 0.025f); }

This code defines a `Pen` with thickness 0. When you use transformations, any lines you draw are also transformed. For this example, I don’t want the lines to be transformed because they would be stretched out of shape. In this case the world coordinates are 10.2 units wide so if I drew a line with thickness 1, it would be scaled so it was about 10% of the width of the drawing area (horizontally). For this example, the line would be almost 50 pixels wide.

If you use a `Pen` with thickness 0, the program draws it one pixel wide no matter how the `Graphics` object is transformed.

After defining the thin pen, the code creates a `Font` to use in labeling the axes. It then sets the `Graphics` object’s `Transform` property to the `Matrix` that maps from world coordinates to the `Bitmap`. After this, any drawing commands will be transformed appropriately.

The code then loops over some x values to draw the X axis.

The following code shows how the program labels the axis.

// Label the X axis. gr.Transform = new Matrix(); gr.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; List<PointF> ints = new List<PointF>(); for (int x = (int)wxmin; x <= wxmax; x++) ints.Add(new PointF(x, -0.07f)); PointF[] ints_array = ints.ToArray(); transform.TransformPoints(ints_array); using (StringFormat sf = new StringFormat()) { sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Near; int index = 0; for (int x = (int)wxmin; x <= wxmax; x++) { gr.DrawString(x.ToString(), font, Brushes.Black, ints_array[index++], sf); } }

If the program simply drew text at this point, it would be transformed by the `Graphics` object’s current transformation so the text would be stretched weirdly. To avoid that, the code resets the `Graphics` object’s `Transform` property to a new identity transformation. Any drawing after this point, including drawing text, will not be transformed.

Of course that means the program can’t use world coordinates to draw the text because they wouldn’t be mapped to the correct locations. To solve that problem the code creates an array of `PointF` holding the locations where it would like to draw the text. It then uses the transformation `Matrix` object’s `TransformPoints` method to transform the points into `Graphics` object coordinates.

Next the program creates a `StringFormat` object to align the text properly and loops through the points drawing X values at the appropriate positions.

The code that draws the Y axis is similar so it isn’t shown here.

The following code shows the rest of the Draw button’s event handler, which draws the distribution curve.

// Draw the curve. gr.Transform = transform; List<PointF> points = new List<PointF>(); float one_over_2pi = (float)(1.0 / (stddev * Math.Sqrt(2 * Math.PI))); float dx = (wxmax - wxmin) / picGraph.ClientSize.Width; for (float x = wxmin; x <= wxmax; x += dx) { float y = F(x, one_over_2pi, mean, stddev, var); points.Add(new PointF(x, y)); } pen.Color = Color.Red; gr.DrawLines(pen, points.ToArray()); } // Font } // Pen picGraph.Image = bm; } }

This code makes a `List<PointF>`. It then divides the width of the world coordinates by the width of the output bitmap so it can plot a value with x equal to each pixel in the bitmap. It loops through those x values and uses the function `F` to adds points to the list. It finishes by converting the list into an array and drawing lines to connect the points.

Pingback: Draw a scaled normal distribution in C# - C# HelperC# Helper

whay its not working with SD = 6336.17094374367 and mean = 29720.81

This example is designed to work with small values near x = 0. Your mean is so far to the right that all of the values near x = 0 are extremely close to 0. In other words, it is drawing the graph, but you can’t see it because the Y values are around 0.000000001.

The other problem is that the standard deviation is so large that the curve is basically very flat and short. The peak is around 0.000006 and spreads out very widely.

You can get a reasonable curve if you do this:

– Comment out the code that draws the axis tic marks

– Comment out the code that labels the axes

– Use the following code to set the world coordinate values:

If you want tic marks and labels on the axes, you’ll need to figure out the spacing. For example, you might label values every 0.00001 along the Y axis and every 5,000 along the X axis.

what is the c# library for your picgraph class

The picGraph control is a PictureBox on the form. This example only uses normal drawing methods, although it does use the following two non-typical namespaces:

Download the example program to see all of the details.