proposed change to colors.py

I've added three function defs at the end of colors.py. The revised
colors.py is attached. (I haven't been able to figure out how to make SVN
save the diff to a file). http://www.nabble.com/file/p25691605/colors.py
colors.py

···

--
View this message in context: http://www.nabble.com/proposed-change-to-colors.py-tp25691605p25691605.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

svn diff > filename

Ryan

···

On Wed, Sep 30, 2009 at 7:47 PM, Dr. Phillip M. Feldman <pfeldman@...778...> wrote:

I've added three function defs at the end of colors.py. The revised
colors.py is attached. (I haven't been able to figure out how to make SVN
save the diff to a file). http://www.nabble.com/file/p25691605/colors.py
colors.py

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Hello Ryan-

Unfortunately, I'm on a Windows system, and it appears that I must use SVN's
GUI interface, which does not provide a mechanism for saving the diff to a
file.

Phillip

<snip>

svn diff > filename

Ryan

···

--
View this message in context: http://www.nabble.com/proposed-change-to-colors.py-tp25691605p25708920.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

From: Dr. Phillip M. Feldman [mailto:pfeldman@…778…]
Sent: Thursday, October 01, 2009 20:45

Unfortunately, I'm on a Windows system, and it appears that I
must use SVN's GUI interface, which does not provide a
mechanism for saving the diff to a file.

Which GUI are you using? If TortoiseSVN, you right-click on the modified file
and select "Create patch..." from the TortoiseSVN menu.

"Create patch" worked. Thanks! The output is attached.

http://www.nabble.com/file/p25734649/colors.py.diff colors.py.diff

From: Dr. Phillip M. Feldman [mailto:pfeldman@…778…]
Sent: Thursday, October 01, 2009 20:45

Unfortunately, I'm on a Windows system, and it appears that I
must use SVN's GUI interface, which does not provide a
mechanism for saving the diff to a file.

Which GUI are you using? If TortoiseSVN, you right-click on the modified
file
and select "Create patch..." from the TortoiseSVN menu.

···

--
View this message in context: http://www.nabble.com/proposed-change-to-colors.py-tp25691605p25734649.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

Hi Philip, all,

This work seems to overlap a lot with the recent color map changes I
committed (matplotlib download | SourceForge.net),
except for the piece-wise constant color maps.

Of course we should avoid duplicate code and work, so perhaps we can
narrow it down to the piece-wise constant part? Please let me know
what you think. We should definitely add a few examples of how to use
this new code, as it might not be that clear directly. Basically the
following is the idea:

import numpy as np
import matplotlib.colors as mcol
import matplotlib.pyplot as plt

stop = mcol.LinearSegmentedColormap.from_list('stop', ['green',
'orange', 'red'])
# or: stop = mcol.LinearSegmentedColormap.from_list('stop', [(0,
'green'), (0.2, 'orange'), (1, 'red')])

x = np.arange(100)
y = x.reshape((5,20))
plt.imshow(y, cmap=stop)
plt.show()

Beside that, I think in no part of MPL we depend on scipy explicitly,
so it would be good to get rid of that. Also, your use of isinstance
should be replaced by the more generic functions in cbook.py (e.g.
is_string_like, is_numlike).

Regards,
Reinier

···

On Sun, Oct 4, 2009 at 4:34 AM, Dr. Phillip M. Feldman <pfeldman@...778...> wrote:

"Create patch" worked. Thanks! The output is attached.

http://www.nabble.com/file/p25734649/colors.py.diff colors.py.diff

From: Dr. Phillip M. Feldman [mailto:pfeldman@…778…]
Sent: Thursday, October 01, 2009 20:45

Unfortunately, I'm on a Windows system, and it appears that I
must use SVN's GUI interface, which does not provide a
mechanism for saving the diff to a file.

Which GUI are you using? If TortoiseSVN, you right-click on the modified
file
and select "Create patch..." from the TortoiseSVN menu.
--
View this message in context: http://www.nabble.com/proposed-change-to-colors.py-tp25691605p25734649.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options

--
Reinier Heeres
Tel: +31 6 10852639

Reinier Heeres wrote:

Hi Philip, all,

This work seems to overlap a lot with the recent color map changes I
committed (matplotlib download | SourceForge.net),
except for the piece-wise constant color maps.

Exactly. And I don't think piece-wise constant maps are a good idea, so I oppose including a function to make them.

Of course we should avoid duplicate code and work, so perhaps we can
narrow it down to the piece-wise constant part? Please let me know
what you think. We should definitely add a few examples of how to use
this new code, as it might not be that clear directly. Basically the
following is the idea:

import numpy as np
import matplotlib.colors as mcol
import matplotlib.pyplot as plt

stop = mcol.LinearSegmentedColormap.from_list('stop', ['green',
'orange', 'red'])
# or: stop = mcol.LinearSegmentedColormap.from_list('stop', [(0,
'green'), (0.2, 'orange'), (1, 'red')])

from_list could have an API more like Phillip's, with an optional argument for the transition points instead of using the sequence of pairs. I'm not sure whether this is an improvement or not, but it has some appeal to me.

One might also argue that instead of being a static method, from_list should be renamed as a free-standing factory function in the colors namespace. Or that such an alias be created.

Eric

···

x = np.arange(100)
y = x.reshape((5,20))
plt.imshow(y, cmap=stop)
plt.show()

Beside that, I think in no part of MPL we depend on scipy explicitly,
so it would be good to get rid of that. Also, your use of isinstance
should be replaced by the more generic functions in cbook.py (e.g.
is_string_like, is_numlike).

Regards,
Reinier

On Sun, Oct 4, 2009 at 4:34 AM, Dr. Phillip M. Feldman > <pfeldman@...778...> wrote:

"Create patch" worked. Thanks! The output is attached.

http://www.nabble.com/file/p25734649/colors.py.diff colors.py.diff

From: Dr. Phillip M. Feldman [mailto:pfeldman@…778…]
Sent: Thursday, October 01, 2009 20:45

Unfortunately, I'm on a Windows system, and it appears that I
must use SVN's GUI interface, which does not provide a
mechanism for saving the diff to a file.

Which GUI are you using? If TortoiseSVN, you right-click on the modified
file
and select "Create patch..." from the TortoiseSVN menu.
--
View this message in context: http://www.nabble.com/proposed-change-to-colors.py-tp25691605p25734649.html
Sent from the matplotlib - devel mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options

Hello Eric-

I'd like to understand the reason why you object to piecewise-constant colormaps. I have found these to be useful for some types of plots. Also, the functionality to create piecewise-constant colormaps is already provided by LinearSegmentedColormap, so "the cat is already out of the bag", so to speak.. (I created my functions mainly because I found the LinearSegmentedColormap interface painful to use. Since then, I have found ways to produce the plots that I need with the existing functions; some of the code isn't very pretty, but this is a secondary consideration).

Eric/Reinier/all:

Is there some way to find out what development tasks are underway so that duplication of effort can be avoided? If there were a list of tasks with associated names and target dates, this would be very useful. (Perhaps something like this already exists, but I have not been able to find it).

Also, it seems as though the HTML documentation is sometimes quite different from the doc strings. I've found the HTML easier to read because of color, italics, etc., but the content of the doc strings is sometimes better and/or quite different. It would be great if these could be harmonized.

Thanks!

Phillip

Eric Firing wrote:

···

Reinier Heeres wrote:

Hi Philip, all,

This work seems to overlap a lot with the recent color map changes I
committed (matplotlib download | SourceForge.net),

except for the piece-wise constant color maps.

Exactly. And I don't think piece-wise constant maps are a good idea, so I oppose including a function to make them.

Of course we should avoid duplicate code and work, so perhaps we can
narrow it down to the piece-wise constant part? Please let me know
what you think. We should definitely add a few examples of how to use
this new code, as it might not be that clear directly. Basically the
following is the idea:

import numpy as np
import matplotlib.colors as mcol
import matplotlib.pyplot as plt

stop = mcol.LinearSegmentedColormap.from_list('stop', ['green',
'orange', 'red'])
# or: stop = mcol.LinearSegmentedColormap.from_list('stop', [(0,
'green'), (0.2, 'orange'), (1, 'red')])

from_list could have an API more like Phillip's, with an optional argument for the transition points instead of using the sequence of pairs. I'm not sure whether this is an improvement or not, but it has some appeal to me.

One might also argue that instead of being a static method, from_list should be renamed as a free-standing factory function in the colors namespace. Or that such an alias be created.

Eric

x = np.arange(100)
y = x.reshape((5,20))
plt.imshow(y, cmap=stop)
plt.show()

Beside that, I think in no part of MPL we depend on scipy explicitly,
so it would be good to get rid of that. Also, your use of isinstance
should be replaced by the more generic functions in cbook.py (e.g.
is_string_like, is_numlike).

Regards,
Reinier

On Sun, Oct 4, 2009 at 4:34 AM, Dr. Phillip M. Feldman >> <pfeldman@...778...> wrote:

"Create patch" worked. Thanks! The output is attached.

http://www.nabble.com/file/p25734649/colors.py.diff colors.py.diff

From: Dr. Phillip M. Feldman [mailto:pfeldman@…778…]
Sent: Thursday, October 01, 2009 20:45

Unfortunately, I'm on a Windows system, and it appears that I
must use SVN's GUI interface, which does not provide a
mechanism for saving the diff to a file.

Which GUI are you using? If TortoiseSVN, you right-click on the modified
file
and select "Create patch..." from the TortoiseSVN menu.
--
View this message in context: http://www.nabble.com/proposed-change-to-colors.py-tp25691605p25734649.html

Sent from the matplotlib - devel mailing list archive at Nabble.com.

Phillip M. Feldman wrote:

Hello Eric-

I'd like to understand the reason why you object to piecewise-constant colormaps. I have found these to be useful for some types of plots.

It is a crude and indirect way of achieving a result that can be achieved precisely and directly using ListedColormap and BoundaryNorm, or possibly a subclass. The problem is that discretization is being done at the wrong stage.

Suppose you have data in the range 1.5 to 2.5, and you want the low third of that range to be red, the middle green, and the upper blue. If you use LinearSegmentedColormap and one of your functions to make a discrete map, then you will have divided your interval of length 1 into 256 segments, which does not allow you to specify exactly 1.5 + 1.0/3 as a transition point. You have only 8 bits of precision available.

What does allow you to specify the transitions exactly (to within the limits of double precision) is this:

cmap = ListedColormap(['r','g','b'])
norm = BoundaryNorm([1.5+1.0/3, 1.5+2.0/3], cmap.N)

Simple, readable, flexible: choose any boundaries you like, specify the colors any way you like, including pulling them out of an existing colormap. Efficient: the cmap lookup table has only as many entries as it needs, and the index into that table is calculated directly in a single step.

Now if you need autoscaling, with the boundaries calculated from vmin and vmax, then this can be done by subclassing BoundaryNorm. In both cases, after using this cmap and norm for a mappable, passing that mappable to colorbar will yield a reasonable result, because colorbar has special code to handle the BoundaryNorm.

Also, the functionality to create piecewise-constant colormaps is already provided by LinearSegmentedColormap, so "the cat is already out of the bag", so to speak.. (I created my functions mainly because I

LinearSegmentedColormap is very general, so yes, it can be used for this.

found the LinearSegmentedColormap interface painful to use. Since then,

That painfulness is exactly the reason why John Hunter added the from_list method 8 months ago (I forgot it had been there that long), and Reinier recently made it more flexible.

I have found ways to produce the plots that I need with the existing functions; some of the code isn't very pretty, but this is a secondary consideration).

You are always welcome to use functions like that in your own code; if they help you, that's fine.

Whenever possible, we want to make it easy for users to plot with pretty code, so if you believe you can't, then either you are not seeing a nice way to do something, or there really is no nice way. In the latter case, an addition or improvement to mpl code may be in order. And in the former case, improvements in documentation and/or examples may be needed.

Eric/Reinier/all:

Is there some way to find out what development tasks are underway so that duplication of effort can be avoided? If there were a list of tasks with associated names and target dates, this would be very useful. (Perhaps something like this already exists, but I have not been able to find it).

No, we operate in a very informal way. Big changes, and sometimes medium and smaller ones, are generally discussed on one of the lists, and that discussion indicates if anyone is actually working on the change. Some smaller and medium changes are simply done when a bee gets under someone's bonnet, leading to a burst of activity. I think most of us have at least short mental lists of things we would like to do, or to see done. All of us are severely constrained by time.

Also, it seems as though the HTML documentation is sometimes quite different from the doc strings. I've found the HTML easier to read because of color, italics, etc., but the content of the doc strings is sometimes better and/or quite different. It would be great if these could be harmonized.

The API html docs are built automatically from the docstrings; the rest of the docs are written manually, and that does tend to lag.

Eric

···

Thanks!

Phillip

Eric Firing wrote:

Reinier Heeres wrote:

Hi Philip, all,

This work seems to overlap a lot with the recent color map changes I
committed (matplotlib download | SourceForge.net),

except for the piece-wise constant color maps.

Exactly. And I don't think piece-wise constant maps are a good idea, so I oppose including a function to make them.

Of course we should avoid duplicate code and work, so perhaps we can
narrow it down to the piece-wise constant part? Please let me know
what you think. We should definitely add a few examples of how to use
this new code, as it might not be that clear directly. Basically the
following is the idea:

import numpy as np
import matplotlib.colors as mcol
import matplotlib.pyplot as plt

stop = mcol.LinearSegmentedColormap.from_list('stop', ['green',
'orange', 'red'])
# or: stop = mcol.LinearSegmentedColormap.from_list('stop', [(0,
'green'), (0.2, 'orange'), (1, 'red')])

from_list could have an API more like Phillip's, with an optional argument for the transition points instead of using the sequence of pairs. I'm not sure whether this is an improvement or not, but it has some appeal to me.

One might also argue that instead of being a static method, from_list should be renamed as a free-standing factory function in the colors namespace. Or that such an alias be created.

Eric

x = np.arange(100)
y = x.reshape((5,20))
plt.imshow(y, cmap=stop)
plt.show()

Beside that, I think in no part of MPL we depend on scipy explicitly,
so it would be good to get rid of that. Also, your use of isinstance
should be replaced by the more generic functions in cbook.py (e.g.
is_string_like, is_numlike).

Regards,
Reinier

On Sun, Oct 4, 2009 at 4:34 AM, Dr. Phillip M. Feldman >>> <pfeldman@...778...> wrote:

"Create patch" worked. Thanks! The output is attached.

http://www.nabble.com/file/p25734649/colors.py.diff colors.py.diff

From: Dr. Phillip M. Feldman [mailto:pfeldman@…778…]
Sent: Thursday, October 01, 2009 20:45

Unfortunately, I'm on a Windows system, and it appears that I
must use SVN's GUI interface, which does not provide a
mechanism for saving the diff to a file.

Which GUI are you using? If TortoiseSVN, you right-click on the modified
file
and select "Create patch..." from the TortoiseSVN menu.
--
View this message in context: http://www.nabble.com/proposed-change-to-colors.py-tp25691605p25734649.html

Sent from the matplotlib - devel mailing list archive at Nabble.com.

Eric Firing wrote:

Phillip M. Feldman wrote:

Hello Eric-

I'd like to understand the reason why you object to piecewise-constant colormaps. I have found these to be useful for some types of plots.

It is a crude and indirect way of achieving a result that can be achieved precisely and directly using ListedColormap and BoundaryNorm, or possibly a subclass. The problem is that discretization is being done at the wrong stage.

Suppose you have data in the range 1.5 to 2.5, and you want the low third of that range to be red, the middle green, and the upper blue. If you use LinearSegmentedColormap and one of your functions to make a discrete map, then you will have divided your interval of length 1 into 256 segments, which does not allow you to specify exactly 1.5 + 1.0/3 as a transition point. You have only 8 bits of precision available.

OK. Good explanation.

What does allow you to specify the transitions exactly (to within the limits of double precision) is this:

cmap = ListedColormap(['r','g','b'])
norm = BoundaryNorm([1.5+1.0/3, 1.5+2.0/3], cmap.N)

Simple, readable, flexible: choose any boundaries you like, specify the colors any way you like, including pulling them out of an existing colormap. Efficient: the cmap lookup table has only as many entries as it needs, and the index into that table is calculated directly in a single step.

Now if you need autoscaling, with the boundaries calculated from vmin and vmax, then this can be done by subclassing BoundaryNorm. In both cases, after using this cmap and norm for a mappable, passing that mappable to colorbar will yield a reasonable result, because colorbar has special code to handle the BoundaryNorm.

Also, the functionality to create piecewise-constant colormaps is already provided by LinearSegmentedColormap, so "the cat is already out of the bag", so to speak.. (I created my functions mainly because I

LinearSegmentedColormap is very general, so yes, it can be used for this.

found the LinearSegmentedColormap interface painful to use. Since then,

That painfulness is exactly the reason why John Hunter added the from_list method 8 months ago (I forgot it had been there that long), and Reinier recently made it more flexible.

When I look at the online documentaiton for from_list, here's what I see: "Make a linear segmented colormap with /name/ from a sequence of /colors/ which evenly transitions from colors[0] at val=1 to colors[-1] at val=1. N is the number of rgb quantization levels." There must be a mistake here, because val=l at both ends. Also, is there web documentation for Reinier's new version?

Thanks!

Phillip

Eric and Reinier-

It seems to me that continuous (piecewise-linear) colormaps could work in much the same fashion. One would specify n boundary colors and n thresholds (for continuous colormaps, I believe that the number of thresholds and colors must be the same), and for any value between two thresholds, the colors associated with the bounding thresholds would be automatically interpolated. What do you think?

Phillip

Eric Firing wrote:

···

What does allow you to specify the transitions exactly (to within the limits of double precision) is this:

cmap = ListedColormap(['r','g','b'])
norm = BoundaryNorm([1.5+1.0/3, 1.5+2.0/3], cmap.N)

I'd like to see a single function that combines ListedColormap and BoundaryNorm. This function could compare the lengths of the color list and threshold list to determine what type of colormap is desired. (If the lengths are the same, then the calling program wants a continuous colormap; if there is one more color than boundaries, the calling program wants a discrete colormap). If this function had optional arguments to specify the `under` and `over` colors, that would be even better.

Phillip

Phillip M. Feldman wrote:

···

Eric and Reinier-

It seems to me that continuous (piecewise-linear) colormaps could work in much the same fashion. One would specify n boundary colors and n thresholds (for continuous colormaps, I believe that the number of thresholds and colors must be the same), and for any value between two thresholds, the colors associated with the bounding thresholds would be automatically interpolated. What do you think?

Phillip

Eric Firing wrote:

What does allow you to specify the transitions exactly (to within the limits of double precision) is this:

cmap = ListedColormap(['r','g','b'])
norm = BoundaryNorm([1.5+1.0/3, 1.5+2.0/3], cmap.N)

Phillip M. Feldman wrote:

When I look at the online documentaiton for from_list, here's what I see: "Make a linear segmented colormap with /name/ from a sequence of /colors/ which evenly transitions from colors[0] at val=1 to colors[-1] at val=1. N is the number of rgb quantization levels." There must be a mistake here, because val=l at both ends. Also, is there web documentation for Reinier's new version?

I'm not sure I know what you mean by web documentation, but in any case, I think all there is at present is the docstring. And yes, that docstring needs work. I'll try to correct and clarify it.

Eric

Phillip M. Feldman wrote:

Eric and Reinier-

It seems to me that continuous (piecewise-linear) colormaps could work in much the same fashion. One would specify n boundary colors and n thresholds (for continuous colormaps, I believe that the number of thresholds and colors must be the same), and for any value between two thresholds, the colors associated with the bounding thresholds would be automatically interpolated. What do you think?

How does this differ from LinearSegmentedColormap.from_list()? I guess what you are getting at is the quantization problem I mentioned in connection with discrete colormaps. But it is not a problem when the colors are linearly interpolated--that is, smoothly varying from one end of the map to the other. It is only a problem when there are jumps.

Eric

···

Phillip

Eric Firing wrote:

What does allow you to specify the transitions exactly (to within the limits of double precision) is this:

cmap = ListedColormap(['r','g','b'])
norm = BoundaryNorm([1.5+1.0/3, 1.5+2.0/3], cmap.N)

I'm not sure whether I'm correctly understanding you. Let's consider a hypothetical engineering performance-versus-requirements scatter plot or contour plot of a performance metric that takes positive values. I'd like to map values to colors so that anything below 50 gets solid red, values from 50 to 70 get a color between red and orange (linear interpolation), values from 70 to 90 get a color between orange and yellow, values from 90 to 105 get a color between yellow and green, and anything greater than or equal to 105 gets solid green. Is this considered "smooth variation"? If so, how would I implement something like this?

Thanks!

Phillip

Eric Firing wrote:

···

Phillip M. Feldman wrote:

Eric and Reinier-

It seems to me that continuous (piecewise-linear) colormaps could work in much the same fashion. One would specify n boundary colors and n thresholds (for continuous colormaps, I believe that the number of thresholds and colors must be the same), and for any value between two thresholds, the colors associated with the bounding thresholds would be automatically interpolated. What do you think?

How does this differ from LinearSegmentedColormap.from_list()? I guess what you are getting at is the quantization problem I mentioned in connection with discrete colormaps. But it is not a problem when the colors are linearly interpolated--that is, smoothly varying from one end of the map to the other. It is only a problem when there are jumps.

Eric

Phillip

Eric Firing wrote:

What does allow you to specify the transitions exactly (to within the limits of double precision) is this:

cmap = ListedColormap(['r','g','b'])
norm = BoundaryNorm([1.5+1.0/3, 1.5+2.0/3], cmap.N)