Graph event probabilities in C#

[event probabilities]

The example Calculate the probability of an event occurring in a given number of trials in C# shows how to calculate event probabilities. This example graphs the results. You can use the example to get some feel for how the probabilities change.

Enter the event probability and the maximum number of trials to perform. When you click Go, the program executes the following code.

// The probability data.
private PointF[] Points = {};

// Calculate and display probabilities.
private void btnGo_Click(object sender, EventArgs e)
{
    // Make room for the probabilities.
    int num_events = int.Parse(txtMaxNumberEvents.Text);
    Points = new PointF[num_events + 1];

    // Get the event probability.
    double event_prob =
        double.Parse(txtEventProb.Text.Replace("%", ""));
    if (txtEventProb.Text.Contains("%")) event_prob /= 100.0;

    // Get the probability of the event not happening.
    double non_prob = 1.0 - event_prob;

    for (int i = 0; i <= num_events; i++)
    {
        Points[i].X = i;
        Points[i].Y = 100 * (float)(1.0 - Math.Pow(non_prob, i));
    }

    // Redraw.
    picGraph.Refresh();
}

The Points array holds the data for the current probability parameters. The Go button’s Click event handler parses the number of events you entered and makes the Points array big enough to hold the event probabilities. The code then parses the event probability and converts it into a decimal value (as in 0.5 instead 50%).

Next the code loops over the desired events calculating the event probabilities and saving the results in the Points array. For drawing convenience, the code stores the probability value as a percentage.

After it has calculated all of the event probabilities, the code refreshes the picGraph PictureBox to make it display the results. The following code shows how the picGraph control’s Paint event handler draws the graph.

// Draw the data.
private void picGraph_Paint(object sender, PaintEventArgs e)
{
    // Clear.
    e.Graphics.Clear(picGraph.BackColor);
    if (Points.Length < 2) return;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    // Transform from world coordinates to screen coordinates.
    RectangleF rect = new RectangleF(0, 0, Points.Length + 1, 100);
    PointF[] pts =
    {
        new PointF(0, picGraph.ClientSize.Height),
        new PointF(picGraph.ClientSize.Width,
                   picGraph.ClientSize.Height),
        new PointF(0, 0)
    };
    Matrix transform = new Matrix(rect, pts);

    using (Pen pen = new Pen(Color.Gray, 0))
    {
        // Draw the axes.
        using (StringFormat sf = new StringFormat())
        {
            sf.LineAlignment = StringAlignment.Center;
            for (int i = 0; i <= 100; i += 10)
            {
                // See where this should be.
                pts = new PointF[]
                {
                    new PointF(0, i),
                    new PointF(Points.Length, i),
                };
                transform.TransformPoints(pts);
                e.Graphics.DrawLine(pen, pts[0], pts[1]);
                e.Graphics.DrawString(i.ToString(), this.Font,
                    Brushes.Green, pts[0], sf);
            }

            sf.Alignment = StringAlignment.Center;
            sf.LineAlignment = StringAlignment.Far;
            int skip = (int)(Points.Length / 10);
            skip = 5 * (int)(skip / 5);
            if (skip < 1) skip = 1;
            for (int i = 0; i < Points.Length; i += skip)
            {
                // See where this should be.
                pts = new PointF[]
                {
                    new PointF(i, 0),
                    new PointF(i, 5),
                };
                transform.TransformPoints(pts);
                e.Graphics.DrawLine(pen, pts[0], pts[1]);
                e.Graphics.DrawString(i.ToString(), this.Font,
                    Brushes.Green, pts[0], sf);
            }
        }

        // Draw the graph.
        pen.Color = Color.Blue;
        e.Graphics.Transform = transform;
        e.Graphics.DrawLines(pen, Points);
    }
}

This code first clears the PictureBox. Then if there are no data points it simply returns.

The code then creates a transformation matrix to transform the data to fit the PictureBox. To do that it creates a RectangleF representing the points’ world coordinate bounds. Those ranges from 0 to 100 in the Y direction (the percentages) and 0 to the number of events in the X direction.

The code also creates an array of points indicating where on the PictureBox the upper left, upper right, and lower left corners of the world coordinate bounds should be mapped. It uses the RectangleF and the array of points to create a Matrix that maps from world coordinates to PictureBox coordinates.

The program then draws the graph. It creates a thin pen to draw with and makes a StringFormat object for use when drawing text.

Next the code draws horizontal lines for every multiple 10% probability. It draws a line connecting the points (0, i) - (Points.Length, i) for i = 10, 20, 30, and so forth. To do this, the code must transform the coordinates of the points so they match up with the transformed points in the graph. It does that by calling the transformation matrix’s TransformPoints method.

After it draws each horizontal line, the code also draws text giving the line’s probability. It positions the text at the line’s left end point (0, i) and centered vertically on the line.

Next the code draws the X axis. It loops over values between 0 and the number of events drawing vertical tick marks and the event numbers.

After drawing the axes and their labels, drawing the actual graph is simple. The code applies the transformation matrix to the Graphics object and calls that object’s DrawLines method to draw the lines.

When you resize the form, the PictureBox control’s Resize event handler also refreshes the PictureBox so you can make the graph bigger if you like.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics, mathematics and tagged , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *