6

Matplotlib's hist says "Compute and draw the histogram of x". I'd like to make a plot without computing anything first. I have the bin widths (unequal), and the total amount in each bin, and I want to plot a frequency-quantity histogram.

For instance, with the data

cm      Frequency
65-75   2
75-80   7
80-90   21
90-105  15
105-110 12

It should make a plot like this:

Histogram

http://www.gcsemathstutor.com/histograms.php

where the area of the blocks represents the frequency in each class.

endolith
  • 25,479
  • 34
  • 128
  • 192

2 Answers2

3

You want a bar chart:

import numpy as np
import matplotlib.pyplot as plt

x = np.sort(np.random.rand(6))
y = np.random.rand(5)

plt.bar(x[:-1], y, width=x[1:] - x[:-1], align='edge')

plt.show()

Here x contains the edges of the bars and y contains the height (not the area!). Note that there is one more element in x than in y because there is one more edge than there are bars.

enter image description here

With original data and area calculation:

from __future__ import division
import numpy as np
import matplotlib.pyplot as plt

frequencies = np.array([2, 7, 21, 15, 12])
bins = np.array([65, 75, 80, 90, 105, 110])

widths = bins[1:] - bins[:-1]
heights = frequencies/widths

plt.bar(bins[:-1], heights, width=widths, align='edge')

plt.show()

histogram with unequal widths

endolith
  • 25,479
  • 34
  • 128
  • 192
David Zwicker
  • 23,581
  • 6
  • 62
  • 77
3

Working on the same as David Zwicker:

import numpy as np
import matplotlib.pyplot as plt

freqs = np.array([2, 7, 21, 15, 12])
bins = np.array([65, 75, 80, 90, 105, 110])
widths = bins[1:] - bins[:-1]
heights = freqs.astype(np.float)/widths
    
plt.fill_between(bins.repeat(2)[1:-1], heights.repeat(2), facecolor='steelblue')
plt.show()

histogram using fill_between

endolith
  • 25,479
  • 34
  • 128
  • 192
Pablo
  • 2,443
  • 1
  • 20
  • 32