question about contours and clim

william ratcliff wrote:

Thanks! I think that explains a lot. In the full range of my dataset, I do have some rather high values. Instead of masking them out, I was hoping that I could just set a minimum and maximum value using clim to only display values within that range--it sounds like I need to mask these values out if I want the contours to be generated automatically. What I'd really like to be able to do is set zlow and zhigh and renormalize the colorbar based on that range (for example, blue the lowest value and red the highest value) for display purposes without touching the underlying data...It might complicate the signature of contour even more, but would it be possible to define a zlow, zhigh, such that the contour levels are determined based on that zlow and zhigh instead of the actual ranges in the data? If they are undefined, the behavior would default to the actual range in the data? That way, one could further separate the display of the data from the actual data...

William,

Yes, it would be possible to put in zlow and zhigh kwargs--but why? Why not just generate the contours you want over the range you want, as I originally suggested? You can use linspace, or arange, or a Ticker. You *don't* need to mask out values that are out of range. You can supply a colormap that uses a color you specify for over-range and under-range values, if you like; see http://matplotlib.sourceforge.net/examples/pylab_examples/image_masked.html
for an example of this (although most of the rest of the example is much more complicated than what you need for contourf.)

Ticker example (untested):

import matplotlib.ticker as ticker
zmin, zmax = 160, 500
locator = ticker.MaxNLocator(10) # if you want no more than 10 contours
locator.set_bounds(zmin, zmax)
levs = locator()
# ... set up x, y, z ...
contourf(x, y, z, levs)

There was an earlier proposal that mappables, like ContourSet, accept norm kwargs vmin and vmax to be passed on to the norm when the default norm is used. I should look at this idea again. I'm not sure offhand whether it is a good idea, or whether it would take care of what you are asking for.

Eric

···

Thanks,
William

On Mon, May 18, 2009 at 6:18 PM, Eric Firing <efiring@...202... > <mailto:efiring@…202…>> wrote:

    william ratcliff wrote:

        Here, I've changed the number of contours to 15 and 45
        respectively--and the problem still remains. Do I need to
        manually set the ranges of the segments on the colorbar or
        something? It would seem to me that somehow the new limits are
        not being used in determining the boundaries of which color is
        used for which set of values. I should also mention that I am
        using a masked array for z (which is what gives rise to the
        white square in the bottom right corner).

    I was not suggesting just changing the *number* of contours, I was
    suggesting explicitly setting the boundaries. This is almost always
    a better strategy; the signature in which a number of contours is
    specified is intended only for quick and dirty exploration (and
    Matlab compatibility, which led to the overly complex set of
    possible signatures for contour in mpl). When contour is called as
    you called it, it doesn't know or care anything about clim; it finds
    the range of your input data and linearly spreads the requested
    number of values over approximately that range. (Actually, it uses
    a ticker to do this, so contour values will fall on reasonably nice
    numbers.) I suspect there is an unmasked high value that is making
    the auto-detected range too large. What do you get from

    print z.min(), z.max()

    If you don't set the clim, it is set automatically based on the
    contour levels; so if you set the levels, you don't need to set the
    clim.

    Colorbar gets its information from the ContourSet object.

    Eric

        Thanks,
        William

        On Mon, May 18, 2009 at 5:16 PM, Eric Firing <efiring@...202... > <mailto:efiring@…202…> <mailto:efiring@…202… > <mailto:efiring@…202…>>> wrote:

           william ratcliff wrote:

               Hi! I have a question about contours and clim within
               matplotlib. I load in some files and do some processing and
               generate a contour plot using:

               cmap=pylab.cm.jet
               mycontour=pylab.contourf(x,y,z,95)#,

                    You don't really want 95 contour levels, do you?
           Instead of using set_clim, set the contour levels you want, and I
           suspect everything will come out OK. E.g.,

           pylab.contourf(x,y,z,pylab.linspace(160, 500, 18))

           Eric

               mycontour.set_clim(vmin=160, vmax=500)
               mycbar=pylab.colorbar()
               mycbar.set_clim(vmin=160, vmax=500)
               pylab.xlim((17,19.6))
               pylab.show()

               However, the behavior is rather unexpected for me. I
        find that
               the colorbar has values rather stretched for values above the
               cutoff specified in clim. Also, are the values
        normalized between
               the limits set in clim, or am I loosing a lot of dynamic
        range?

               Thanks,
               William

Thanks! I’ll just add that if you want to use the ticker example it needs to be:

zmin, zmax = 160, 500

locator = ticker.MaxNLocator(10) # if you want no more than 10 contours

locator.create_dummy_axis()

locator.set_bounds(zmin, zmax)

levs = locator()

···

On Mon, May 18, 2009 at 7:29 PM, Eric Firing <efiring@…202…> wrote:

william ratcliff wrote:

Thanks! I think that explains a lot. In the full range of my dataset, I do have some rather high values. Instead of masking them out, I was hoping that I could just set a minimum and maximum value using clim to only display values within that range–it sounds like I need to mask these values out if I want the contours to be generated automatically. What I’d really like to be able to do is set zlow and zhigh and renormalize the colorbar based on that range (for example, blue the lowest value and red the highest value) for display purposes without touching the underlying data…It might complicate the signature of contour even more, but would it be possible to define a zlow, zhigh, such that the contour levels are determined based on that zlow and zhigh instead of the actual ranges in the data? If they are undefined, the behavior would default to the actual range in the data? That way, one could further separate the display of the data from the actual data…

William,

Yes, it would be possible to put in zlow and zhigh kwargs–but why? Why not just generate the contours you want over the range you want, as I originally suggested? You can use linspace, or arange, or a Ticker. You don’t need to mask out values that are out of range. You can supply a colormap that uses a color you specify for over-range and under-range values, if you like; see http://matplotlib.sourceforge.net/examples/pylab_examples/image_masked.html

for an example of this (although most of the rest of the example is much more complicated than what you need for contourf.)

Ticker example (untested):

import matplotlib.ticker as ticker

zmin, zmax = 160, 500

locator = ticker.MaxNLocator(10) # if you want no more than 10 contours

locator.set_bounds(zmin, zmax)

levs = locator()

… set up x, y, z …

contourf(x, y, z, levs)

There was an earlier proposal that mappables, like ContourSet, accept norm kwargs vmin and vmax to be passed on to the norm when the default norm is used. I should look at this idea again. I’m not sure offhand whether it is a good idea, or whether it would take care of what you are asking for.

Eric

Thanks,

William

On Mon, May 18, 2009 at 6:18 PM, Eric Firing <efiring@…202… mailto:efiring@...202...> wrote:

william ratcliff wrote:



    Here, I've changed the number of contours to 15 and 45

    respectively--and the problem still remains.  Do I need to

    manually set the ranges of the segments on the colorbar or

    something?  It would seem to me that somehow the new limits are

    not being used in determining the boundaries of which color is

    used for which set of values.  I should also mention that I am

    using a masked array for z (which is what gives rise to the

    white square in the bottom right corner).





I was not suggesting just changing the *number* of contours, I was

suggesting explicitly setting the boundaries. This is almost always

a better strategy; the signature in which a number of contours is

specified is intended only for quick and dirty exploration (and

Matlab compatibility, which led to the overly complex set of

possible signatures for contour in mpl). When contour is called as

you called it, it doesn't know or care anything about clim; it finds

the range of your input data and linearly spreads the requested

number of values over approximately that range.  (Actually, it uses

a ticker to do this, so contour values will fall on reasonably nice

numbers.) I suspect there is an unmasked high value that is making

the auto-detected range too large. What do you get from



print z.min(), z.max()





If you don't set the clim, it is set automatically based on the

contour levels; so if you set the levels, you don't need to set the

clim.



Colorbar gets its information from the ContourSet object.





Eric





    Thanks,

    William





    On Mon, May 18, 2009 at 5:16 PM, Eric Firing <efiring@...202...

mailto:efiring@...202... <mailto:efiring@…202…

    <mailto:efiring@...202...>>> wrote:



       william ratcliff wrote:



           Hi!   I have a question about contours and clim within

           matplotlib.  I load in some files and do some processing and

           generate a contour plot using:





           cmap=pylab.cm.jet

           mycontour=pylab.contourf(x,y,z,95)#,









               You don't really want 95 contour levels, do you?

       Instead of using set_clim, set the contour levels you want, and I

       suspect everything will come out OK.  E.g.,



       pylab.contourf(x,y,z,pylab.linspace(160, 500, 18))



       Eric



           mycontour.set_clim(vmin=160, vmax=500)

           mycbar=pylab.colorbar()

           mycbar.set_clim(vmin=160, vmax=500)

           pylab.xlim((17,19.6))

           pylab.show()





           However, the behavior is rather unexpected for me.  I

    find that

           the colorbar has values rather stretched for values above the

           cutoff specified in clim.  Also, are the values

    normalized between

           the limits set in clim, or am I loosing a lot of dynamic

    range?





           Thanks,

           William