|
From: Benjamin R. <ben...@ou...> - 2010-08-11 03:22:53
|
On Tue, Aug 10, 2010 at 7:39 PM, Benjamin Root <ben...@ou...> wrote: > On Tue, Aug 10, 2010 at 7:20 PM, Eric Firing <ef...@ha...> wrote: > >> On 08/10/2010 11:58 AM, Friedrich Romstedt wrote: >> > 2010/8/10 Eric Firing<ef...@ha...>: >> >> On 08/10/2010 10:27 AM, Friedrich Romstedt wrote: >> >>> So I think it is probably best to code it into the Colormap object >> >>> itself, so that each and ever derived class can define its own method >> >>> of how to create a greyscale version. What do you think about that? >> >> >> >> Good idea. The base class could define a default to_grayscale() method >> >> that would do the conversion near the very end of the Colormap.__call__ >> >> method if an as_gray attribute, also defined in the base class, is >> True. >> >> No need for getters and setters--let it be a simple attribute. This >> >> is much simpler than generating a whole new colormap--instead, just set >> >> an attribute to switch an existing colormap to gray or back to color. >> I >> >> would leave the switch out of the __init__ args and kwargs. >> > >> >> If someone >> >> wants grey, they can add one more line of code to set the attribute. >> > >> > Hmm, one would have to do it for every colormap used. Also, it would >> > be not so obvious if using the default colormap. >> > >> >> I >> >> suspect only a small fraction of users will need this. >> > >> > I like this, it's a good idea enabling to not repeat all the stuff in >> > the code. But hey, wouldn't it be the same to just overload the >> > __call__ method? >> > >> > class GrayColorbar(RgbColorbar): >> > """A colorbar returning grayscaled version.""" >> > >> > def __call__(self, value): >> > """Transforms RgbColorbar's value into grayscale, and returns >> it."""" >> > >> > rgb = BaseClass.__call__(self, value) >> > [do stuff] >> > return grayscale >> >> Why make a whole new class instead of switching a behavior in an >> existing class? >> >> > >> > Agreed, one has to this for all the classes, while your solution works >> > generically in ColormapBase or whatever it's called. >> >> I think my solution (with slight modification) is also very compatible >> with your suggestion below to have an rc param that switches between >> color and gray. If as_gray is None, use the rc value; otherwise, let it >> act as described above. >> >> The typical use case is when one wants color initially, but then must >> regenerate plots in black and white to reduce publication costs. Your >> rc suggestion facilitates such switching. >> >> > >> > Another option would be, to wrap the Colormap into a thin layer with >> > __call__, but this appears way too clumsy and too hacky to me. It's a >> > clumsy way of deriving from the class. Otherwise it's maybe also >> > nice, because it's generic, for all Colormaps. __getattr__ and >> > __setattr__ (iirc) could be used to simulate the wrapped instance >> > fully. >> >> I don't follow you on this--I don't understand at all. >> >> >> > >> > Is there some layer dealing with colors in the renderers, where the >> > conversion could also happen? I'm asking because of displaying color >> > images etc. and printing them as grayscale. With this, we would get >> > rid of the alpha stuff completely, too. >> >> I don't understand why you would want to push this down into the >> renderers instead of keeping it at a higher level. And I don't know >> what you mean by "getting rid of the alpha stuff". >> >> > >> > Maybe a general matplotlib.rc switch 'greyscale' would be possible. >> > It would leave room for tons of improvement, e.g. automatically >> > setting the color cycle to - -- -. etc., there was some monthes ago >> > discussion about how to achieve that. Another advantage: It's zero >> > loc if set in the config file ;-) >> >> Yes, there does seem to be a need for these sorts of switching >> operations. Getting back to the colormap question, our discussions have >> been based on the assumption that an rgb_to_gray function is all that is >> needed. But is this true? Or will users actually need completely >> different graymaps rather than something resembling a black-and-white >> photo of a colormap? If so, then my suggested strategy is useless. >> >> Eric >> >> > >> > I think that would be a real neat new feature. >> > >> > I agree what's not needed is mixed greyscale and colour display in the >> > same Figure. >> > >> > Bear with me if my ideas are always too radical. >> > >> > Friedrich >> >> > I have to agree with Eric on this. Maybe I am just not understanding > Friedrich's thought process. > > If someone wants a specific greyscale colormapping, then they can make it > themselves just like any other colormap. However, it is as a matter of > convenience and ease to say "hey, I have this colormap that I have been > using in my code, but I need its greyscale equivalent". > > My idea is this. It appears that all colormappings get a lookup table > (self._lut) that contains rgba values. We could also simultaneously > maintain a second lookup table (initialized only when needed). Therefore, > one could take a colormap, switch on the greyscale attribute when desired > (which would swap the two tables), and switch back over to the color-scale > with the same amount of ease. > > It would be independent of any Colormap subclass because it would be in the > base class. My only concern is when do the various drawing elements > actually use the colormap info? If I create a b&w figure in one subplot, > but also a colored figure in another subplot (for whatever reason) using the > same colormap, would the figure show as expected at render-time? > > Thoughts, concerns, comments? > > Ben Root > Ok, I have made some code that let's me easily switch between modes and works quite nicely. However, something I suspected would happen occurs. If I were to use the colormap and ever change the mode before rendering, *all* places where that colormap was used is colored according to the mode last set before rendering. This could be considered a bug or a feature, depending on one's viewpoint. I suspect if one really needed independent colormaps, one could use deepcopy before applying the alternate colormap to the axes. I am including a patch to this email for a looking over (be brutal). Note, it is hardly ready for inclusion as I am sure there are some other behaviors I haven't thought of. Below is a quick example of how to use the new feature. Enjoy! Ben Root import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm X, Y = np.mgrid[-10:10, -10:10] Z = np.abs(X * Y) cmap = cm.get_cmap() cmap.grey_mode = True plt.pcolor(X, Y, Z, cmap=cmap) plt.show() |