Is it turned off by a single error in imshow?

I draw a PGM image: enter image description here Here is the data that I use.

The problem is that some of the pixels shown are erroneous. For instance:

  • the three gray rectangles at the top of the image have a value of 11 (so they should be red, not red).
  • two yellow pixels in the top row - they have a value of 8, so they should be yellow-green, not yellow.

Can someone explain the discrepancies and how to fix them?

Here is my source:

from pylab import *
import numpy    
LABELS = range(13)
NUM_MODES = len(LABELS)
def read_ascii_pgm(fname):
    """
    Very fragile PGM reader.  It OK since this is only for reading files
    output by my own app.
    """
    lines = open(fname).read().strip().split('\n')
    assert lines[0] == 'P2'
    width, height = map(int, lines[1].split(' '))
    assert lines[2] == '13'
    pgm = numpy.zeros((height, width), dtype=numpy.uint8)
    for i in range(height):
        cols = lines[3+i].split(' ')
        for j in range(width):
            pgm[i,j] = int(cols[j])
    return pgm
def main():
    import sys
    assert len(sys.argv) > 1
    fname = sys.argv[1]
    pgm = read_ascii_pgm(fname)
    # EDIT: HACK!
    pgm[0,0] = 12
    cmap = cm.get_cmap('spectral', NUM_MODES)
    imshow(pgm, cmap=cmap, interpolation='nearest')
    edit = True
    if edit:
        cb = colorbar()
    else:
        ticks = [ (i*11./NUM_MODES + 6./NUM_MODES) for i in range(NUM_MODES) ]
        cb = colorbar(ticks=ticks)
        cb.ax.set_yticklabels(map(str, LABELS))
    savefig('imshow.png')
if __name__ == '__main__':
    main()

EDIT

I see what is happening here now. Basically, imshowit seems to do this:

  • dynamic range determination (as [ min(image), max(image) ]
  • represent this using the number of colors indicated in the color map (13 colors)

What I want to do:

  • , (13)
  • , 13

, 13 (. HACK). ?

: enter image description here

+5
2

im.set_clim(vmin, vmax). . , 3 , .

, max_nodes - (13 ), , . im.set_clim(0, 13).

, num_modes:

import numpy
from pylab import *

def read_ascii_pgm(fname):
    lines = open(fname).read().strip().split('\n')
    assert lines[0] == 'P2'
    width, height = map(int, lines[1].split(' '))
    num_modes = int(lines[2])
    pgm = numpy.zeros((height, width), dtype=numpy.uint8)
    for i in range(height):
        cols = lines[3+i].split(' ')
        for j in range(width):
            pgm[i,j] = int(cols[j])
    return pgm, num_modes + 1

if __name__ == '__main__':
    import sys
    assert len(sys.argv) > 1
    fname = sys.argv[1]
    pgm, num_modes = read_ascii_pgm(fname)
    labels = range(num_modes)
    cmap = cm.get_cmap('spectral', num_modes)
    im = imshow(pgm, cmap=cmap, interpolation='nearest')
    im.set_clim(0, num_modes)
    ticks = [(i + 0.5) for i in range(num_modes)]
    cb = colorbar(ticks=ticks)
    cb.ax.set_yticklabels(map(str, labels))
    savefig('imshow_new.png')

. , num_modes 10, . , 1:1:

P2
5 3
10
0 1 0 2 0
3 0 2 0 1
0 1 0 2 0

:

enter image description here

+5

, , , , .

, LABELS range(13), (ticks) 0 12.

, , 10.6, 12!

cb.ax.set_yticklabels(map(str, LABELS)), , ( , matplotlib . map(str, LABELS)).

, , , ? - [round(tick) for tick in ticks]?

: , , ... , !:)

Edit2: , , imshow . ( ... ?)

, , LinearSegmentedColormap. , matplotlib LinearSegmentedColormap ( matplotlib.cm.spectral).

, set_clim([0,12]) coloraxis, imshow.

.

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np

with open('temp.pgm') as infile:
    header, nrows, ncols = [infile.readline().strip() for _ in range(3)]
    data = np.loadtxt(infile).astype(np.uint8)

cmap = mpl.cm.get_cmap('spectral', 13)
cax = plt.imshow(data, cmap, interpolation='nearest')
cax.set_clim([0,13])
cbar = plt.colorbar(cax, ticks=np.arange(0.5, 13, 1.0))
cbar.ax.set_yticklabels(range(13))
plt.show()

enter image description here

+3

All Articles