2

I have plotted a histogram

of a grayscale image

with matplotlib. But the histogram does not look like what I want.

from matplotlib import pyplot as plt 
import numpy as np
from PIL import Image
im=Image.open("lena.pgm")
pxl=list(im.getdata())
print pxl
columnsize,rowsize=im.size

a = np.array(pxl)
plt.hist(a, bins = 255)
plt.title("histogram") 
plt.show()

I want the histogram like

3
  • What features are you after, exactly? The number of bins? The colors? Commented Jan 6, 2019 at 8:22
  • @ MadPhysicist There is a blank vertical strip in the produced histogram. I don't want this. And the color of the vertical strip should be the same as the last image Commented Jan 6, 2019 at 8:26
  • See this SO answer, stackoverflow.com/a/23062183/4902099. Basically you need to map a range of colors to your data in order to generate the histogram you want. Commented Jan 6, 2019 at 10:23

2 Answers 2

2

The gaps in the histogram are due to a poor choice of bin size. If you call hist(..., bins=255), numpy will create 256 bins from the min-value to the max-value of your array. In other words, the bins will have non-integer width (in my tests: [ 24. , 24.86666667, 25.73333333, 26.6 , ....]).

Because you are dealing with an image with 255 levels, you should create 255 bins of width 1:

plt.hist(a, bins=range(256))

We have to write 256 because we need to include the right-most edge of the bins, otherwise points with a value of 255 would not be included.

As for the color, follow the examples in the question linked in the comments

from PIL import Image
im=Image.open("lena.pgm")
a = np.array(im.getdata())

fig, ax = plt.subplots(figsize=(10,4))
n,bins,patches = ax.hist(a, bins=range(256), edgecolor='none')
ax.set_title("histogram")
ax.set_xlim(0,255)


cm = plt.cm.get_cmap('cool')
norm = matplotlib.colors.Normalize(vmin=bins.min(), vmax=bins.max())
for b,p in zip(bins,patches):
    p.set_facecolor(cm(norm(b)))
plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

You can use the plt.hist() method like so:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('lena.png', 0)
plt.hist(img.ravel(), 256, (0, 256))
plt.show()

Output:

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.