Custom colormap is inconsistent. What is wrong?

I'm trying to create a custom colormap used with pcolormesh, but the
results seem inconsistent to me. I want the following colors

-3 < x <= -2 ----- Black
-2 < x <= -1 ----- Blue
-1 < x <= 0 ----- Yellow
0 < x <= 1 ----- Green
1 < x <= inf ----- Red

A minimal example is copied below. I have a 2-D array that looks like:

-1, 6, 2.5
1.3, -2, 4/3
2.5, 6, 0

I want to get a pcolormesh that looks like

R R Y
R K R
B R R

But instead I get:

Y R B
Y K Y
K R Y

I recognize that the pcolormesh is plotted "upside-down" from how the
matrix is printed. I apparently don't understand how to use a custom
colormap. I have tried to follow the example here:

http://matplotlib.sourceforge.net/examples/api/colorbar_only.html

but haven't been too successful. It seems like there is a
normalization going on that I can't seem to track down. Can anyone
see what is wrong?

Thanks,
Jeremy

import numpy
import matplotlib.pyplot as pyplot
import matplotlib.colors

C = numpy.array([[-1,6,2.5],[4/3., -2, 4/3.],[2.5,6,0.0]],dtype=float)

cMap = matplotlib.colors.ListedColormap(['k', 'b', 'y', 'g', 'r'])
Bounds = [-3.0, -2.0, -1.0, 0.0, 1.0, numpy.inf]

# Plot
Fig = pyplot.figure()
pyplot.pcolormesh(C, cmap=cMap)

Have you given imshow() a try? The pcolor() and family are really meant for more general domain specifications. imshow() is about as basic as one can get for producing an image that shows the colors for particular values. matshow() also does something similar and doesn’t interpolate between points.

I don’t know if it would fix your problem, but it should be a good start.

Ben Root

···

On Tue, Feb 1, 2011 at 5:48 PM, Jeremy Conlin <jlconlin@…287…> wrote:

I’m trying to create a custom colormap used with pcolormesh, but the

results seem inconsistent to me. I want the following colors

-3 < x <= -2 ----- Black

-2 < x <= -1 ----- Blue

-1 < x <= 0 ----- Yellow

0 < x <= 1 ----- Green

1 < x <= inf ----- Red

A minimal example is copied below. I have a 2-D array that looks like:

-1, 6, 2.5

1.3, -2, 4/3

2.5, 6, 0

I want to get a pcolormesh that looks like

R R Y

R K R

B R R

But instead I get:

Y R B

Y K Y

K R Y

I recognize that the pcolormesh is plotted “upside-down” from how the

matrix is printed. I apparently don’t understand how to use a custom

colormap. I have tried to follow the example here:

http://matplotlib.sourceforge.net/examples/api/colorbar_only.html

but haven’t been too successful. It seems like there is a

normalization going on that I can’t seem to track down. Can anyone

see what is wrong?

Thanks,

Jeremy

import numpy

import matplotlib.pyplot as pyplot

import matplotlib.colors

C = numpy.array([[-1,6,2.5],[4/3., -2, 4/3.],[2.5,6,0.0]],dtype=float)

cMap = matplotlib.colors.ListedColormap([‘k’, ‘b’, ‘y’, ‘g’, ‘r’])

Bounds = [-3.0, -2.0, -1.0, 0.0, 1.0, numpy.inf]

Plot

Fig = pyplot.figure()

pyplot.pcolormesh(C, cmap=cMap)

I just tried both imshow and matshow and they gave the same output,
but the plot was rotated -90º. I don't care so much about how it is
oriented, but I do care about consistency, i.e. -1 should be plotted
as blue, but is instead black. I could also accept -1 as yellow since
-1 is on the boundary. pcolor, imshow, and matshow all show the same
inconsistency.

Jeremy

···

On Tue, Feb 1, 2011 at 5:00 PM, Benjamin Root <ben.root@...1304...> wrote:

On Tue, Feb 1, 2011 at 5:48 PM, Jeremy Conlin <jlconlin@...287...> wrote:

I'm trying to create a custom colormap used with pcolormesh, but the
results seem inconsistent to me. I want the following colors

-3 < x <= -2 ----- Black
-2 < x <= -1 ----- Blue
-1 < x <= 0 ----- Yellow
0 < x <= 1 ----- Green
1 < x <= inf ----- Red

A minimal example is copied below. I have a 2-D array that looks like:

-1, 6, 2.5
1.3, -2, 4/3
2.5, 6, 0

I want to get a pcolormesh that looks like

R R Y
R K R
B R R

But instead I get:

Y R B
Y K Y
K R Y

I recognize that the pcolormesh is plotted "upside-down" from how the
matrix is printed. I apparently don't understand how to use a custom
colormap. I have tried to follow the example here:

http://matplotlib.sourceforge.net/examples/api/colorbar_only.html

but haven't been too successful. It seems like there is a
normalization going on that I can't seem to track down. Can anyone
see what is wrong?

Thanks,
Jeremy

import numpy
import matplotlib.pyplot as pyplot
import matplotlib.colors

C = numpy.array([[-1,6,2.5],[4/3., -2, 4/3.],[2.5,6,0.0]],dtype=float)

cMap = matplotlib.colors.ListedColormap(['k', 'b', 'y', 'g', 'r'])
Bounds = [-3.0, -2.0, -1.0, 0.0, 1.0, numpy.inf]

# Plot
Fig = pyplot.figure()
pyplot.pcolormesh(C, cmap=cMap)

Have you given imshow() a try? The pcolor() and family are really meant for
more general domain specifications. imshow() is about as basic as one can
get for producing an image that shows the colors for particular values.
matshow() also does something similar and doesn't interpolate between
points.

I don't know if it would fix your problem, but it should be a good start.

I think I just figured out what is wrong. In your code, you create a ListedColormap, but you don’t assign a Norm object. So, when you call pcolor or whatever, it will use the default norm using the range of input values. I see you created a list of boundaries called Bounds, but you don’t do anything with it.

I believe you want to first make a BoundaryNorm object using Bounds and pass that object to the ListedColormap using the norm keyword.

That should fix it.

Ben Root

···

On Tue, Feb 1, 2011 at 6:05 PM, Jeremy Conlin <jlconlin@…287…> wrote:

On Tue, Feb 1, 2011 at 5:00 PM, Benjamin Root <ben.root@…1304…> wrote:

On Tue, Feb 1, 2011 at 5:48 PM, Jeremy Conlin <jlconlin@…287…> wrote:

I’m trying to create a custom colormap used with pcolormesh, but the

results seem inconsistent to me. I want the following colors

-3 < x <= -2 ----- Black

-2 < x <= -1 ----- Blue

-1 < x <= 0 ----- Yellow

0 < x <= 1 ----- Green

1 < x <= inf ----- Red

A minimal example is copied below. I have a 2-D array that looks like:

-1, 6, 2.5

1.3, -2, 4/3

2.5, 6, 0

I want to get a pcolormesh that looks like

R R Y

R K R

B R R

But instead I get:

Y R B

Y K Y

K R Y

I recognize that the pcolormesh is plotted “upside-down” from how the

matrix is printed. I apparently don’t understand how to use a custom

colormap. I have tried to follow the example here:

http://matplotlib.sourceforge.net/examples/api/colorbar_only.html

but haven’t been too successful. It seems like there is a

normalization going on that I can’t seem to track down. Can anyone

see what is wrong?

Thanks,

Jeremy

import numpy

import matplotlib.pyplot as pyplot

import matplotlib.colors

C = numpy.array([[-1,6,2.5],[4/3., -2, 4/3.],[2.5,6,0.0]],dtype=float)

cMap = matplotlib.colors.ListedColormap([‘k’, ‘b’, ‘y’, ‘g’, ‘r’])

Bounds = [-3.0, -2.0, -1.0, 0.0, 1.0, numpy.inf]

Plot

Fig = pyplot.figure()

pyplot.pcolormesh(C, cmap=cMap)

Have you given imshow() a try? The pcolor() and family are really meant for

more general domain specifications. imshow() is about as basic as one can

get for producing an image that shows the colors for particular values.

matshow() also does something similar and doesn’t interpolate between

points.

I don’t know if it would fix your problem, but it should be a good start.

I just tried both imshow and matshow and they gave the same output,

but the plot was rotated -90º. I don’t care so much about how it is

oriented, but I do care about consistency, i.e. -1 should be plotted

as blue, but is instead black. I could also accept -1 as yellow since

-1 is on the boundary. pcolor, imshow, and matshow all show the same

inconsistency.

Jeremy

Jeremy Conlin, on 2011-02-01 16:48, wrote:

I'm trying to create a custom colormap used with pcolormesh, but the
results seem inconsistent to me. I want the following colors

-3 < x <= -2 ----- Black
-2 < x <= -1 ----- Blue
-1 < x <= 0 ----- Yellow
0 < x <= 1 ----- Green
1 < x <= inf ----- Red

A minimal example is copied below. I have a 2-D array that looks like:

-1, 6, 2.5
1.3, -2, 4/3
2.5, 6, 0

I want to get a pcolormesh that looks like

R R Y
R K R
B R R

But instead I get:

Y R B
Y K Y
K R Y

I recognize that the pcolormesh is plotted "upside-down" from how the
matrix is printed. I apparently don't understand how to use a custom
colormap. I have tried to follow the example here:

http://matplotlib.sourceforge.net/examples/api/colorbar_only.html

but haven't been too successful. It seems like there is a
normalization going on that I can't seem to track down. Can anyone
see what is wrong?

Thanks,
Jeremy

import numpy
import matplotlib.pyplot as pyplot
import matplotlib.colors

C = numpy.array([[-1,6,2.5],[4/3., -2, 4/3.],[2.5,6,0.0]],dtype=float)

cMap = matplotlib.colors.ListedColormap(['k', 'b', 'y', 'g', 'r'])
Bounds = [-3.0, -2.0, -1.0, 0.0, 1.0, numpy.inf]

# Plot
Fig = pyplot.figure()
pyplot.pcolormesh(C, cmap=cMap)

Hi Jeremy,

you're right, matplotlib expects colors to be in the range 0-1.
I've added the appropriate normalization below. I also had to
subtract a small number from C to adjust for your specification
of the desired intervals being closed on the upper bound, because
the default makes lower bound closed. In other words, the default
is to treat the bounds as -3 <= x < -2 for black, in your case,
instead of -3 < x <= -2 as you wanted it.

  # R R Y
  # R K R
  # B R R
  n = mpl.colors.normalize(-3,2)
  pyplot.pcolormesh(C-(1e-15), cmap=cMap,norm=n)

     >
     >>
     >> I'm trying to create a custom colormap used with pcolormesh, but the
     >> results seem inconsistent to me. I want the following colors
     >>
     >> -3 < x <= -2 ----- Black
     >> -2 < x <= -1 ----- Blue
     >> -1 < x <= 0 ----- Yellow
     >> 0 < x <= 1 ----- Green
     >> 1 < x <= inf ----- Red
     >>
     >> A minimal example is copied below. I have a 2-D array that
    looks like:
     >>
     >> -1, 6, 2.5
     >> 1.3, -2, 4/3
     >> 2.5, 6, 0
     >>
     >> I want to get a pcolormesh that looks like
     >>
     >> R R Y
     >> R K R
     >> B R R
     >>
     >> But instead I get:
     >>
     >> Y R B
     >> Y K Y
     >> K R Y
     >>
     >> I recognize that the pcolormesh is plotted "upside-down" from
    how the
     >> matrix is printed. I apparently don't understand how to use a
    custom
     >> colormap. I have tried to follow the example here:
     >>
     >> http://matplotlib.sourceforge.net/examples/api/colorbar_only.html
     >>
     >> but haven't been too successful. It seems like there is a
     >> normalization going on that I can't seem to track down. Can anyone
     >> see what is wrong?
     >>
     >> Thanks,
     >> Jeremy
     >>
     >> import numpy
     >> import matplotlib.pyplot as pyplot
     >> import matplotlib.colors
     >>
     >> C = numpy.array([[-1,6,2.5],[4/3., -2,
    4/3.],[2.5,6,0.0]],dtype=float)
     >>
     >> cMap = matplotlib.colors.ListedColormap(['k', 'b', 'y', 'g', 'r'])
     >> Bounds = [-3.0, -2.0, -1.0, 0.0, 1.0, numpy.inf]
     >>
     >> # Plot
     >> Fig = pyplot.figure()
     >> pyplot.pcolormesh(C, cmap=cMap)
     >>
     >
     > Have you given imshow() a try? The pcolor() and family are
    really meant for
     > more general domain specifications. imshow() is about as basic
    as one can
     > get for producing an image that shows the colors for particular
    values.
     > matshow() also does something similar and doesn't interpolate between
     > points.
     >
     > I don't know if it would fix your problem, but it should be a
    good start.

    I just tried both imshow and matshow and they gave the same output,
    but the plot was rotated -90º. I don't care so much about how it is
    oriented, but I do care about consistency, i.e. -1 should be plotted
    as blue, but is instead black. I could also accept -1 as yellow since
    -1 is on the boundary. pcolor, imshow, and matshow all show the same
    inconsistency.

    Jeremy

I think I just figured out what is wrong. In your code, you create a
ListedColormap, but you don't assign a Norm object. So, when you call
pcolor or whatever, it will use the default norm using the range of
input values. I see you created a list of boundaries called Bounds, but
you don't do anything with it.

I believe you want to first make a BoundaryNorm object using Bounds and
pass that object to the ListedColormap using the norm keyword.

Not to the ListedColormap, but to the imshow or whatever. Here is an example of BoundaryNorm:

http://matplotlib.sourceforge.net/examples/pylab_examples/image_masked.html

And here is another, using a BoundaryNorm with a ListedColormap:

http://matplotlib.sourceforge.net/examples/pylab_examples/multicolored_line.html

(It is the first of the two line plots.)

Note that you need to instantiate it with the number of colors in your colormap.

Eric

···

On 02/01/2011 02:18 PM, Benjamin Root wrote:

On Tue, Feb 1, 2011 at 6:05 PM, Jeremy Conlin <jlconlin@...287... > <mailto:jlconlin@…287…>> wrote:
    On Tue, Feb 1, 2011 at 5:00 PM, Benjamin Root <ben.root@...1304... > <mailto:ben.root@…1304…>> wrote:
     > On Tue, Feb 1, 2011 at 5:48 PM, Jeremy Conlin <jlconlin@...287... > <mailto:jlconlin@…287…>> wrote:

That should fix it.

Ben Root

Thanks everyone for there help. You were right, it was a
normalization problem. I added a normalization and now I get what I
want (see final code below).

Jeremy

import numpy
import matplotlib.pyplot as pyplot
import matplotlib.colors

C = numpy.array([[-1,6,2.5],[4/3., -2, 4/3.],[2.5,6,0.0]],dtype=float)

cMap = matplotlib.colors.ListedColormap(['k', 'b', 'y', 'g', 'r'])
Bounds = [-3.0, -2.0, -1.0, 0.0, 1.0, numpy.inf]
Norm = matplotlib.colors.BoundaryNorm(Bounds, cMap.N)

# Plot
Fig = pyplot.figure()
pyplot.pcolormesh(C-1E-15, cmap=cMap, norm=Norm)

···

On Tue, Feb 1, 2011 at 6:31 PM, Eric Firing <efiring@...202...> wrote:

On 02/01/2011 02:18 PM, Benjamin Root wrote:

On Tue, Feb 1, 2011 at 6:05 PM, Jeremy Conlin <jlconlin@...287... >> <mailto:jlconlin@…287…>> wrote:

On Tue, Feb 1, 2011 at 5:00 PM, Benjamin Root &lt;ben\.root@\.\.\.3421\.\.\.\.\. &gt;&gt;     &lt;mailto:ben.root@...1304...&gt;&gt; wrote:
 &gt;
 &gt;
 &gt; On Tue, Feb 1, 2011 at 5:48 PM, Jeremy Conlin &lt;jlconlin@\.\.\.83\.\.\.287\.\.\. &gt;&gt;     &lt;mailto:jlconlin@...287...&gt;&gt; wrote:
 &gt;&gt;
 &gt;&gt; I&#39;m trying to create a custom colormap used with pcolormesh, but the
 &gt;&gt; results seem inconsistent to me\.  I want the following colors
 &gt;&gt;
 &gt;&gt; \-3 &lt; x &lt;= \-2 \-\-\-\-\- Black
 &gt;&gt; \-2 &lt; x &lt;= \-1 \-\-\-\-\- Blue
 &gt;&gt; \-1 &lt; x &lt;= 0  \-\-\-\-\- Yellow
 &gt;&gt;  0 &lt; x &lt;= 1  \-\-\-\-\- Green
 &gt;&gt;  1 &lt; x &lt;= inf \-\-\-\-\- Red
 &gt;&gt;
 &gt;&gt; A minimal example is copied below\.  I have a 2\-D array that
looks like:
 &gt;&gt;
 &gt;&gt;  \-1,    6,  2\.5
 &gt;&gt; 1\.3,  \-2,  4/3
 &gt;&gt; 2\.5,   6,  0
 &gt;&gt;
 &gt;&gt; I want to get a pcolormesh that looks like
 &gt;&gt;
 &gt;&gt; R R Y
 &gt;&gt; R K R
 &gt;&gt; B R R
 &gt;&gt;
 &gt;&gt; But instead I get:
 &gt;&gt;
 &gt;&gt; Y R B
 &gt;&gt; Y K Y
 &gt;&gt; K R Y
 &gt;&gt;
 &gt;&gt; I recognize that the pcolormesh is plotted &quot;upside\-down&quot; from
how the
 &gt;&gt; matrix is printed\.  I apparently don&#39;t understand how to use a
custom
 &gt;&gt; colormap\.  I have tried to follow the example here:
 &gt;&gt;
 &gt;&gt; http://matplotlib.sourceforge.net/examples/api/colorbar_only.html
 &gt;&gt;
 &gt;&gt; but haven&#39;t been too successful\.  It seems like there is a
 &gt;&gt; normalization going on that I can&#39;t seem to track down\.  Can anyone
 &gt;&gt; see what is wrong?
 &gt;&gt;
 &gt;&gt; Thanks,
 &gt;&gt; Jeremy
 &gt;&gt;
 &gt;&gt;
 &gt;&gt; import numpy
 &gt;&gt; import matplotlib\.pyplot as pyplot
 &gt;&gt; import matplotlib\.colors
 &gt;&gt;
 &gt;&gt; C = numpy\.array\(\[\[\-1,6,2\.5\],\[4/3\., \-2,
4/3\.\],\[2\.5,6,0\.0\]\],dtype=float\)
 &gt;&gt;
 &gt;&gt; cMap = matplotlib\.colors\.ListedColormap\(\[&#39;k&#39;, &#39;b&#39;, &#39;y&#39;, &#39;g&#39;, &#39;r&#39;\]\)
 &gt;&gt; Bounds = \[\-3\.0, \-2\.0, \-1\.0, 0\.0, 1\.0, numpy\.inf\]
 &gt;&gt;
 &gt;&gt; \# Plot
 &gt;&gt; Fig = pyplot\.figure\(\)
 &gt;&gt; pyplot\.pcolormesh\(C, cmap=cMap\)
 &gt;&gt;
 &gt;
 &gt; Have you given imshow\(\) a try?  The pcolor\(\) and family are
really meant for
 &gt; more general domain specifications\.  imshow\(\) is about as basic
as one can
 &gt; get for producing an image that shows the colors for particular
values\.
 &gt; matshow\(\) also does something similar and doesn&#39;t interpolate between
 &gt; points\.
 &gt;
 &gt; I don&#39;t know if it would fix your problem, but it should be a
good start\.

I just tried both imshow and matshow and they gave the same output,
but the plot was rotated \-90º\.  I don&#39;t care so much about how it is
oriented, but I do care about consistency, i\.e\. \-1 should be plotted
as blue, but is instead black\.  I could also accept \-1 as yellow since
\-1 is on the boundary\.  pcolor, imshow, and matshow all show the same
inconsistency\.

Jeremy

I think I just figured out what is wrong. In your code, you create a
ListedColormap, but you don't assign a Norm object. So, when you call
pcolor or whatever, it will use the default norm using the range of
input values. I see you created a list of boundaries called Bounds, but
you don't do anything with it.

I believe you want to first make a BoundaryNorm object using Bounds and
pass that object to the ListedColormap using the norm keyword.

Not to the ListedColormap, but to the imshow or whatever. Here is an
example of BoundaryNorm:

http://matplotlib.sourceforge.net/examples/pylab_examples/image_masked.html

And here is another, using a BoundaryNorm with a ListedColormap:

http://matplotlib.sourceforge.net/examples/pylab_examples/multicolored_line.html

(It is the first of the two line plots.)

Note that you need to instantiate it with the number of colors in your
colormap.

Eric