## required packages/modules
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
from IPython.display import display, HTML

## default font style
rcParams["font.family"] = "serif"

## format output
CSS = """
.output {
  margin-left:20;
}
"""

HTML('<style>{}</style>'.format(CSS))

Frequency Polygons

Defining The Term

  • A frequency polygon, like a histogram, is a graphical display of class frequencies.

  • In a frequency polygon, we do not use bars to represent class frequency. Instead, we plot each class frequency as a dot at the class midpoint, and then the dots are connected by a series of line segment.

Steps to Draw Frequency Polygon

  • Step 01: Mark the middle values of each class interval on the x-axis, also called class-mark.

  • Step 02: Mark the frequency of the class on the y-axis.

  • Step 03: For each class interval's midpoint mark the frequency.

  • Step 04: Connect these points using the line segment.

  • The obtained plot is a frequency polygon.

Example

  • Let's walk through an example to see how to plot a frequency polygon.

  • For the given frequency distribution we will plot a frequency polygon.

Class Intervals Frequency
30.0 - under 40.0 1
40.0 - under 50.0 3
50.0 - under 60.0 5
60.0 - under 70.0 4
70.0 - under 80.0 15
80.0 - under 90.0 5
90.0 - under 100.0 7
  • The first thing we need to do is to calculate the midpoint for each class intervals.
Class Intervals Frequency Class Midpoint
30.0 - under 40.0 1 (40 + 30) / 2 = 35
40.0 - under 50.0 3 (50 + 40) / 2 = 45
50.0 - under 60.0 5 (60 + 50) / 2 = 55
60.0 - under 70.0 4 (70 + 60) / 2 = 65
70.0 - under 80.0 15 (80 + 70) / 2 = 75
80.0 - under 90.0 5 (90 + 80) / 2 = 85
90.0 - under 100.0 7 (100 + 90) / 2 = 95
  • Now, we will plot class-midpoints on the x-axis and corresponding frequencies on the y-axis.

def create_axis(
    xticks, yticks, xlim, ylim, 
    xlabel="Class Interval",
    ylabel="Frequency"
):
    """
    Function to create axis.
    
    Args:
        xticks (numpy.array): xtick values.
        yticks (numpy.array): ytick values.
        xlim (tuple): x-limit.
        ylim (tuple): y-limit.
        xlabel (str, optional): X label value.
        ylabel (str, optional): y label value.
    
    Returns:
        figure.Figure: figure object.
        axes.Axes: axes object.
    """
    ## create subplot
    fig, ax = plt.subplots(facecolor="#121212", figsize=(12,8))
    ax.set_facecolor("#121212")

    ## hide the all the spines
    ax.spines["right"].set_visible(False)
    ax.spines["top"].set_visible(False)

    ## change color
    ax.spines['bottom'].set_color("#F2F2F2")
    ax.spines['left'].set_color("#F2F2F2") 

    ## change color of tick params
    ax.tick_params(axis='x', colors="#F2F2F2")
    ax.tick_params(axis='y', colors="#F2F2F2")

    ## set ticks
    ax.set_xticks(np.round(xticks, 2))
    ax.set_yticks(np.round(yticks, 2))

    ## set labels
    ax.set_xlabel(xlabel, color="#F2F2F2", size=20)
    ax.set_ylabel(ylabel, color="#F2F2F2", size=20)

    ## setting the limit
    ax.set(xlim=xlim, ylim=ylim)

    ## credits
    fig.text(
        0.9, 0.02, "graphic: @slothfulwave612", 
        fontsize=10, fontstyle="italic", color="#F2F2F2",
        ha="right", va="center"
    )
    
    return fig, ax

fig, ax = create_axis(
    xticks=np.arange(35,96,10), yticks=np.linspace(0,15,16), 
    xlim=(30,101), ylim=(0,15),
    xlabel="Class Mark"
)

plt.show()
  • For our first class interval, we have class midpoint value as 35 and frequency as 1.

  • So, we will plot a point at (35,1).

# plot the first class-frequency
ax.scatter(35, 1, s=50, fc="#F2F2F2")

fig
  • For our second class interval, we have class midpoint value as 45 and frequency as 3.

  • So, we will plot a point at (45,3).

# plot the second class-frequency
ax.scatter(45, 3, s=50, fc="#F2F2F2")

fig
  • We do the same process for the remaining class intervals, and the resulting plot looks like this:

# create the axis
fig, ax = create_axis(
    xticks=np.arange(35,96,10), yticks=np.linspace(0,15,16), 
    xlim=(30,101), ylim=(0,15.3),
    xlabel="Class-Midpoint"
)

# class-midpoints and frequencies
x_coord = np.arange(35,96,10)
y_coord = np.array([1, 3, 5, 4, 15, 5, 7])

# plot the points
ax.scatter(
    x_coord, y_coord, s=50, fc="#F2F2F2", zorder=2
)

plt.show()
  • And the final step is to connect these dots with line segments, so our frequency polygon for the given frequency distribution looks like this:

# connect the dots
ax.plot(x_coord, y_coord, color="skyblue", zorder=1)

fig
  • The information obtained from frequency polygons and histograms are similar.

  • As with the histogram, changing the scales of the axis can compress or stretch a frequency polygon, which affects the user’s impression of what the graph represents.

Ogives

  • An ogives (o-jive) is a cumulative frequency polygon.

Steps to Draw Ogives

  • Calculate the cumulative-frequency.

  • Mark the endpoints of each class-interval on the x-axis, and the y-axis with the cumulative-frequency.

  • We plot a dot of zero frequency at the beginning of the first class.

  • Then we proceed by marking a dot at the end of each class intervals for the cumulative value.

  • Connecting the dots with line segments completes the construction of ogive.

Example

  • Let's take the same frequency distribution.
Class Intervals Frequency
30.0 - under 40.0 1
40.0 - under 50.0 3
50.0 - under 60.0 5
60.0 - under 70.0 4
70.0 - under 80.0 15
80.0 - under 90.0 5
90.0 - under 100.0 7
  • So, our first step is to calculate cumulative frequency for the given frequency distribution.
Class Intervals Frequency Cumulative Frequency
30.0 - under 40.0 1 1
40.0 - under 50.0 3 4
50.0 - under 60.0 5 9
60.0 - under 70.0 4 13
70.0 - under 80.0 15 28
80.0 - under 90.0 5 33
90.0 - under 100.0 7 40
  • Now the next step is to plot points on our x-axis and y-axis.

    • On x-axis we will plot endpoints of each class interval(for the first class interval we will plot both the start and end points).

    • On y-axis we will plot the cumulative frequency.

# create axis
fig, ax = create_axis(
    xticks=np.arange(30,101,10), yticks=np.arange(0,41,5),
    xlim=(29,101), ylim=(-1,41), 
    xlabel="Class Endpoints", ylabel="Cumulative Frequency"
)
  • We will now plot our first dot (a dot of zero frequency), which will be at the beginning of the first class, i.e. at 30.

ax.scatter(
    30, 0, s=50, color="#F2F2F2", zorder=2
)
fig
  • Now, we will plot all the cumulative frequencies corresponding to their class-endpoints.

# coordinates
x_coord = np.arange(40,101,10)
freq = np.array([1, 4, 9, 13, 28, 33, 40])

# scatter the points
ax.scatter(
    x_coord, freq, s=50, zorder=2, color="#F2F2F2"
)

fig
  • And the last step is to join these dots by line segments.

ax.plot(
    np.insert(x_coord, 0, 30), np.insert(freq, 0, 0),
    color="skyblue", zorder=1
)

fig
  • The above plot is our required ogive.

  • We can use ogives when we want to see running totals (or cumulative sum).

  • The presence of steep slopes in an ogive identifies a sharp increase in frequencies.

    • e.g. a steep slope occurs in the class-interval 70 - under 80, signifying a large jump in class frequency totals.

Questionnaire

Ques 01: Construct a histogram and a frequency polygon for the following data.

Class Intervals Frequency
30 - under 32 5
32 - under 34 7
34 - under 36 15
36 - under 38 21
38 - under 40 34
40 - under 42 24
42 - under 44 17
44 - under 46 8

Ques 02: Construct a histogram and a frequency polygon for the following data.

Class Intervals Frequency
10 - under 20 9
20 - under 30 7
30 - under 40 10
40 - under 50 6
50 - under 60 13
60 - under 70 18
70 - under 80 15

Ques 03: Construct an ogive for the following data.

Class Intervals Frequency
3 - under 6 2
6 - under 9 5
9 - under 12 10
12 - under 15 11
15 - under 18 17
18 - under 21 5

1. Notes are compiled from Business Statistics by Ken Black

2. If you face any problem or have any feedback/suggestions feel free to comment.