discrete non-uniform intervals colorbar

I wish to make a color filled plot with the colors defined for discrete, non-uniform intervals. Something like:
0.0 -0.001 0.001-0.05 0.05-0.2 0.2-0.4 0.4-0.8 0.8-1.0
    red blue green magenta yellow cyan

with the colorbar labeled appropriately.
I have seen discussions and solutions for discrete colors but not for non-uniform intervals + discrete.
The last post I saw regarding this type of issue was august 2005 - and a solution was not resolved at that time.
However, Eric has done a huge amount of work in the intervening time and a smarter person than myself might have a solution now.

Note that I do not wish just to make contours - although that would be good - but to have a general mapping code that joins allows the color rmapping to be passed to colorbar.
maybe some sub-class of scalarMappable that could work.

Thanks for any help.

--Jim

James Boyle wrote:

I wish to make a color filled plot with the colors defined for discrete, non-uniform intervals. Something like:
0.0 -0.001 0.001-0.05 0.05-0.2 0.2-0.4 0.4-0.8 0.8-1.0
    red blue green magenta yellow cyan

with the colorbar labeled appropriately.
I have seen discussions and solutions for discrete colors but not for non-uniform intervals + discrete.
The last post I saw regarding this type of issue was august 2005 - and a solution was not resolved at that time.
However, Eric has done a huge amount of work in the intervening time and a smarter person than myself might have a solution now.

Note that I do not wish just to make contours - although that would be good - but to have a general mapping code that joins allows the color rmapping to be passed to colorbar.
maybe some sub-class of scalarMappable that could work.

This is very easy for contourf, and is illustrated in the second figure made by examples/contourf_demo.py. For your case above, it would be something like

levs = [0, 0.001, 0.05, 0.2, 0.4, 0.8, 1]
colors = ['r', 'b', 'g', 'm', 'y', 'c']
contourf(z, levs, colors=colors)
colorbar()

Unfortunately, although it *should* be just as easy for imshow or pcolor, it is not at present; it can be done, probably in several ways, but not in such a transparent way. Attached is a quick attempt at something that might be close to what you need. The right way to do this is to make some changes and additions to colors.py and colorbar.py; I might get to that in a few days, or, more likely, it might be a few weeks.

Eric

discrete_pcolor.py (864 Bytes)

···

Thanks for any help.

--Jim

Eric,
Thanks for the quick reply.
I should have looked more closely at the examples for the contourf solution.
As I indicated, my problem is a bit beyond contours. I have routines that fill polygons ( finite element mesh) using a specified color map.
The ability to fill areas with the proper color is easy - getting the corresponding color bar has been the more interesting part.
It is going to take some time to look over your suggestion to see how I could implement it in my application.
Presently I sub-class scalarMappable, and set the appropriate values and pass this to colorbar(). However, I have not been able to figure out how to do this for non-uniform intervals.
This is a long winded way of saying that getting pcolor and matshow to work may or may not solve my specific problem.

Thanks again,

--Jim

···

On Apr 18, 2007, at 1:52 AM, Eric Firing wrote:

James Boyle wrote:

I wish to make a color filled plot with the colors defined for discrete, non-uniform intervals. Something like:
0.0 -0.001 0.001-0.05 0.05-0.2 0.2-0.4 0.4-0.8 0.8-1.0
    red blue green magenta yellow cyan
with the colorbar labeled appropriately.
I have seen discussions and solutions for discrete colors but not for non-uniform intervals + discrete.
The last post I saw regarding this type of issue was august 2005 - and a solution was not resolved at that time.
However, Eric has done a huge amount of work in the intervening time and a smarter person than myself might have a solution now.
Note that I do not wish just to make contours - although that would be good - but to have a general mapping code that joins allows the color rmapping to be passed to colorbar.
maybe some sub-class of scalarMappable that could work.

This is very easy for contourf, and is illustrated in the second figure made by examples/contourf_demo.py. For your case above, it would be something like

levs = [0, 0.001, 0.05, 0.2, 0.4, 0.8, 1]
colors = ['r', 'b', 'g', 'm', 'y', 'c']
contourf(z, levs, colors=colors)
colorbar()

Unfortunately, although it *should* be just as easy for imshow or pcolor, it is not at present; it can be done, probably in several ways, but not in such a transparent way. Attached is a quick attempt at something that might be close to what you need. The right way to do this is to make some changes and additions to colors.py and colorbar.py; I might get to that in a few days, or, more likely, it might be a few weeks.

Eric

Thanks for any help.
--Jim

import pylab as P
import numpy
from matplotlib import colors

class BoundaryNorm(colors.Normalize):
    def __init__(self, boundaries):
        self.vmin = boundaries[0]
        self.vmax = boundaries[-1]
        self.boundaries = boundaries
        self.N = len(self.boundaries)

    def __call__(self, x, clip=False):
        x = numpy.asarray(x)
        ret = numpy.zeros(x.shape, dtype=numpy.int)
        for i, b in enumerate(self.boundaries):
            ret[numpy.greater_equal(x, b)] = i
        ret[numpy.less(x, self.vmin)] = -1
        ret = numpy.ma.asarray(ret / float(self.N-1))
        return ret

bounds = [0, 0.1, 0.5, 1]
cm = colors.ListedColormap(['r', 'g', 'b'])

z = (numpy.arange(5)[:,None] * numpy.arange(8)[None,:]).astype(numpy.float)
z = z / z.max()

P.pcolor(z, cmap=cm, norm=BoundaryNorm(bounds))
P.colorbar(boundaries=bounds)
P.show()

James Boyle wrote:

Eric,
Thanks for the quick reply.
I should have looked more closely at the examples for the contourf solution.
As I indicated, my problem is a bit beyond contours. I have routines that fill polygons ( finite element mesh) using a specified color map.
The ability to fill areas with the proper color is easy - getting the corresponding color bar has been the more interesting part.
It is going to take some time to look over your suggestion to see how I could implement it in my application.
Presently I sub-class scalarMappable, and set the appropriate values and pass this to colorbar(). However, I have not been able to figure out how to do this for non-uniform intervals.
This is a long winded way of saying that getting pcolor and matshow to work may or may not solve my specific problem.

I think that something close to my example should do the job. It sounds like your difficulty is with the colorbar; but colorbar gives quite a bit of control via the kwargs, and you can also drop back from colorbar.Colorbar (which the pylab colorbar command uses) to colorbar.ColorbarBase, using the colorbar.Colorbar code as an example.

I don't think you should need to use an intermediate ScalarMappable subclass, although this may be a perfectly good approach.

Eric

···

Thanks again,

--Jim

On Apr 18, 2007, at 1:52 AM, Eric Firing wrote:

James Boyle wrote:

I wish to make a color filled plot with the colors defined for discrete, non-uniform intervals. Something like:
0.0 -0.001 0.001-0.05 0.05-0.2 0.2-0.4 0.4-0.8 0.8-1.0
    red blue green magenta yellow cyan
with the colorbar labeled appropriately.
I have seen discussions and solutions for discrete colors but not for non-uniform intervals + discrete.
The last post I saw regarding this type of issue was august 2005 - and a solution was not resolved at that time.
However, Eric has done a huge amount of work in the intervening time and a smarter person than myself might have a solution now.
Note that I do not wish just to make contours - although that would be good - but to have a general mapping code that joins allows the color rmapping to be passed to colorbar.
maybe some sub-class of scalarMappable that could work.

This is very easy for contourf, and is illustrated in the second figure made by examples/contourf_demo.py. For your case above, it would be something like

levs = [0, 0.001, 0.05, 0.2, 0.4, 0.8, 1]
colors = ['r', 'b', 'g', 'm', 'y', 'c']
contourf(z, levs, colors=colors)
colorbar()

Unfortunately, although it *should* be just as easy for imshow or pcolor, it is not at present; it can be done, probably in several ways, but not in such a transparent way. Attached is a quick attempt at something that might be close to what you need. The right way to do this is to make some changes and additions to colors.py and colorbar.py; I might get to that in a few days, or, more likely, it might be a few weeks.

Eric

Thanks for any help.
--Jim

import pylab as P
import numpy
from matplotlib import colors

class BoundaryNorm(colors.Normalize):
    def __init__(self, boundaries):
        self.vmin = boundaries[0]
        self.vmax = boundaries[-1]
        self.boundaries = boundaries
        self.N = len(self.boundaries)

    def __call__(self, x, clip=False):
        x = numpy.asarray(x)
        ret = numpy.zeros(x.shape, dtype=numpy.int)
        for i, b in enumerate(self.boundaries):
            ret[numpy.greater_equal(x, b)] = i
        ret[numpy.less(x, self.vmin)] = -1
        ret = numpy.ma.asarray(ret / float(self.N-1))
        return ret

bounds = [0, 0.1, 0.5, 1]
cm = colors.ListedColormap(['r', 'g', 'b'])

z = (numpy.arange(5)[:,None] * numpy.arange(8)[None,:]).astype(numpy.float)
z = z / z.max()

P.pcolor(z, cmap=cm, norm=BoundaryNorm(bounds))
P.colorbar(boundaries=bounds)
P.show()

Dear folks,

I tried to plot a colored map with non-uniformed discrete colorbar and found a few threads related with this. However, I could not find a way to apply non-uniformed discrete colorbar over imshow or pcolor. Would anybody give me a clue? Thanks in advance.

Kim

Eric Firing wrote:

···

James Boyle wrote:

I wish to make a color filled plot with the colors defined for discrete, non-uniform intervals. Something like:
0.0 -0.001 0.001-0.05 0.05-0.2 0.2-0.4 0.4-0.8 0.8-1.0
    red blue green magenta yellow cyan

with the colorbar labeled appropriately.
I have seen discussions and solutions for discrete colors but not for non-uniform intervals + discrete.
The last post I saw regarding this type of issue was august 2005 - and a solution was not resolved at that time.
However, Eric has done a huge amount of work in the intervening time and a smarter person than myself might have a solution now.

Note that I do not wish just to make contours - although that would be good - but to have a general mapping code that joins allows the color rmapping to be passed to colorbar.
maybe some sub-class of scalarMappable that could work.

This is very easy for contourf, and is illustrated in the second figure made by examples/contourf_demo.py. For your case above, it would be something like

levs = [0, 0.001, 0.05, 0.2, 0.4, 0.8, 1]
colors = ['r', 'b', 'g', 'm', 'y', 'c']
contourf(z, levs, colors=colors)
colorbar()

Unfortunately, although it *should* be just as easy for imshow or pcolor, it is not at present; it can be done, probably in several ways, but not in such a transparent way. Attached is a quick attempt at something that might be close to what you need. The right way to do this is to make some changes and additions to colors.py and colorbar.py; I might get to that in a few days, or, more likely, it might be a few weeks.

Eric

Thanks for any help.

--Jim

------------------------------------------------------------------------

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
------------------------------------------------------------------------

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users