Login
📚 Python for Introductory Statistics
Chapters ▾

5.4 Histogram, Polygon and Ogive

A histogram uses connected bars to represent the frequency distribution of a continuous dataset.

Syntax for n bins(classes)

import matplotlib.pyplot as plt
plt.hist(x,bins=n,ec='k')

Example: The dataset below is scores of 20 students in a Math class. Write a program to construct a histogram with 5 classes(bins).

33, 42, 49, 49, 53, 55, 55, 61, 63, 67, 68, 68, 69, 69, 72, 73, 74,78, 80, 83, 88, 88, 88, 90, 92, 94, 94, 94, 94, 96, 100

Deom Video Link

  1. Click + Code
  2. Type import matplotlib.pyplot as plt
  3. Type x = [33, 42, 49, 49, 53, 55, 55, 61, 63, 67, 68, 68, 69, 69, 72, 73, 74,78, 80, 83, 88, 88, 88, 90, 92, 94, 94, 94, 94, 96, 100]
  4. Type plt.hist(x,bins=5,ec='k')
  5. Click play button

Note: ec='k' adds solid black lines to the bars.

import matplotlib.pyplot as plt
x = [33, 42, 49, 49, 53, 55, 55, 61, 63, 67, 68, 68, 69, 69, 72, 73, 74,78, 80, 
     83, 88, 88, 88, 90, 92, 94, 94, 94, 94, 96, 100]
plt.hist(x,bins=5,ec='k')
Show expected output
(array([ 2.,  5.,  9.,  4., 11.]),
 array([ 33. ,  46.4,  59.8,  73.2,  86.6, 100. ]),
 <a list of 5 Patch objects>)
Histogram of the 31 exam scores (33 to 100) in five classes with black bar edges; class frequencies run 2, 5, 9, 4 and 11, so the top class up to 100 is tallest.

Example: The dataset below is scores of 20 students in a Math class. Write a program to construct a histogram with 5 classes(bins). Use class limits for the x-axis.

33, 42, 49, 49, 53, 55, 55, 61, 63, 67, 68, 68, 69, 69, 72, 73, 74,78, 80, 83, 88, 88, 88, 90, 92, 94, 94, 94, 94, 96, 100

  1. Click + Code
  2. Type import matplotlib.pyplot as plt
  3. Type x = [33, 42, 49, 49, 53, 55, 55, 61, 63, 67, 68, 68, 69, 69, 72, 73, 74,78, 80, 83, 88, 88, 88, 90, 92, 94, 94, 94, 94, 96, 100]
  4. Type (freq, class_limit, patches) = plt.hist(x,bins=5)
  5. Type plt.xticks(class_limit)
  6. Click play button
import matplotlib.pyplot as plt
x = [33, 42, 49, 49, 53, 55, 55, 61, 63, 67, 68, 68, 69, 69, 72, 73, 74, 
           78, 80, 83, 88, 88, 88, 90, 92, 94, 94, 94, 94, 96, 100]

(freq,class_limit,patches) = plt.hist(x,bins=5,ec='k')
plt.xticks(class_limit)
Show expected output
([<matplotlib.axis.XTick at 0x7fcbbda5b910>,
  <matplotlib.axis.XTick at 0x7fcbbda5b490>,
  <matplotlib.axis.XTick at 0x7fcbbda5b950>,
  <matplotlib.axis.XTick at 0x7fcbbda3bad0>,
  <matplotlib.axis.XTick at 0x7fcbbda3bc50>,
  <matplotlib.axis.XTick at 0x7fcbbda45590>],
 <a list of 6 Text major ticklabel objects>)
The same five-class histogram of the 31 exam scores with the horizontal-axis ticks moved to the class boundaries 33, 46.4, 59.8, 73.2, 86.6 and 100.

Example: Histograms from raw data

Use the US Senators age data given below and write a program to:

  1. Make a histogram with 5 bins (classes) and age range of 40 to 90
  2. Display the frequencies and bins(classes)
  3. Add titles and labels

81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,43,42,41

import matplotlib.pyplot as plt

age = [81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,
        70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,
        63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,
        56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,
        43,42,41]

(freq, bins, patches) = plt.hist(age,bins=5,edgecolor='white', range=[40,90])

plt.suptitle("Histogram")
plt.xlabel("Age")
plt.ylabel("Freq")

print("bins", bins)
print("freq",freq)
Show expected output
bins [40. 50. 60. 70. 80. 90.]
freq [10. 29. 34. 21.  6.]
Histogram titled Histogram of the 100 ages, five classes of width 10 from 40 to 90 with white edges: frequencies 10, 29, 34, 21 and 6, peaking in the 60s class; axes labeled Age and Freq.

Interpretation from the above output for bins and frequencies:

binsfrequency
40-5010
50-6029
60-7034
70-8021
80-906

key: 40-50 is [40,60)

Frequency Polygon

A frequency polygon is a line graph connecting midpoints of each class/bin.

Example: Use the above example (Senators age) to construct a frequency polygon.

We will use the function below to construct a polygon. The arguments (input) to the function are the data values, x, and number of classes(bins), n.

Python Functions

A function is a block of code which only runs when it is called. You can pass data, known as arguments, into a function. A function can return data as a result. In Python a function is defined using the def keyword.

Syntax

def func_name(data):
    statement(s)
    return result  # optional

When the function func_name(x) is called it will return result.

To graph a frequency polygon, use the function polygon(x,n) given below. x is the dataset list and n is the number of classes/bins.

def polygon(x,n):
  import matplotlib.pyplot as plt
  import numpy as np

  freq, bins, edges = plt.hist(x,bins=n,ec="k",range=[min(x),max(x)+1])
  plt.title("Frequency Polygon")
  plt.xlabel('Midpoint data values')
  plt.ylabel('Frequency')

  a1=bins[0]-(bins[1]-bins[0])
  a2=bins[-1]+(bins[1]-bins[0])
  bin1=np.insert(bins,[0],a1)
  bin1=np.append(bin1,a2)

  freq,edges,_=plt.hist(x,bins=bin1,ec='k', facecolor='blue', range=[min(x),max(x)+1])
  midpoints=0.5*(edges[1:]+edges[:-1])
  plt.plot(midpoints,freq)
#  plt.xticks(bin1)
  plt.xticks(midpoints)
  plt.show()

Example: Use the the polygon(x,n) function above to plot a frequency polygon of the US Senators age data given below with 5 bins(classes).

81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,43,42,41

Watch demo video

  1. Click play button on the above code def polygon(x,n)
  2. Type x = [81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,43,42,41]
  3. Type polygon(x,5)
  4. Click on play button
x = [81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,
        70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,
        63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,
        56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,
        43,42,41]
polygon(x,5)
Frequency polygon of the same 100 ages in five classes: a line through the class-midpoint frequencies rising to 34 in the 60s class and falling to 6 in the 80s class.

Ogive

Ogive is a line graph that displays cumulative frequency of each (upper) class. To graph an ogive, use the function ogive(x,n) given below. x is the dataset list and n is the number of classes/bins.

def ogive(x,n):
  import matplotlib.pyplot as plt
  import numpy as np

  freq, bins, edges = plt.hist(x,bins=n,ec="k",range=[min(x),max(x)+1])
  plt.title("Ogive")
  plt.xlabel('data values')
  plt.ylabel('Cumulative frequency')

  a1=bins[0]-(bins[1]-bins[0])
  a2=bins[-1]+(bins[1]-bins[0])
  bin1=np.insert(bins,[0],a1)
  bin1=np.append(bin1,a2)

  freq,edges,_=plt.hist(x,bins=bin1,ec='k', facecolor='blue', range=[min(x),max(x)+1])

  ogive1 = edges[:-1]
  cumfreq = np.cumsum(freq)
  plt.plot(ogive1,cumfreq)
  plt.xticks(bin1)
  plt.show()

Example: Use the ogive(x,n) function above to plot an ogive of the US Senators age data given below with 5 bins(classes).

81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,43,42,41

Watch demo video

  1. Click play button on the above code def ogive(x,n)
  2. Type x = [81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,43,42,41]
  3. Type ogive(x,5)
  4. Click on play button
x = [81,81,80,80,80,80,78,78,78,77,77,75,75,74,74,74,73,72,72,71,71,71,71,70,70,
        70,70,68,68,68,68,68,67,67,67,66,66,65,65,65,65,64,64,64,64,64,64,63,63,
        63,63,62,62,62,62,62,61,61,61,60,60,59,59,59,59,59,59,59,59,58,58,57,57,
        56,56,55,54,54,54,54,54,53,53,52,52,52,52,52,51,50,49,48,46,45,44,43,43,
        43,42,41]
ogive(x,5)
Ogive (cumulative frequency curve) of the 100 ages: the line climbs from 0 before age 40 through 10, 39, 73 and 94 to 100 at age 90.

Adapted from Python for Introductory Statistics, by Simon Aman (Truman College, City Colleges of Chicago), licensed under CC BY 4.0. Changes were made: reformatted as an accessible XYZ web edition with live in-browser code cells. License: CC-BY-4.0.