From: Eric E. <ems...@ob...> - 2005-01-12 08:07:36
|
Hi, I think what you sent me may help although what you describe looks very much like I have done in the piece of code I sent. It is not a first priority since what I wrote is ''kind of working'' (if I reload things everytime I display) but indeed an ''easy'' solution to this problem would be most welcome. The worry I have is that at the moment we cannot load the lut without describing the datad keys and so on so that it looks like a never ending story if people ask the developers everytime to update the cm/colors files. (otherwise it crashes when you do imshow repeatedly) As for the Question 3: - I wish to load my array in LINEAR but then load a lut in LOG, so that the sampling of the SAME lut is done but in LOG instead of LINEAR (so the fact that it is in log would only appear when you load the color bar). This is used often when I need to display a set of images side by side, some being in LIN, others in LOG. My idea is the following: - it is I think (may be wrong) feasible to add a functionality during the mapping of the lut (when the LinearSegmented array is sampled on 256 levels) so that it takes the LOG10, LN, EXP, or '-' (* -1 to invert a lut) of the abscissa so that the required effect appears. This would create a smashed lut, or an inverted one. etc... See what I mean? Eric Perry Greenfield wrote: > > On Jan 11, 2005, at 10:25 AM, Eric Emsellem wrote: > >> HI again, >> >> I have questions of how to generate new LUTs outside matplotlib. >> >> 3 main issues: >> >> 1/ how to create a new lut in the same way that cm.py/colors.py is >> doing it >> in matplotlib >> 2/ how to create a new lut which is given by a set of e.g., 256 >> colours levels (R, G, B) >> but not as a segmented array as in cm/colors >> 3/ How do you rescale a lut without rescaling the array itself? >> (so an equivalent to load/itt log for example in Midas for those who >> know). >> For example I would like to use the jet lut but with a log increase >> of the lut so that e.g. displaying the color bar shows it is in ''log'' >> >> For 1, I am not so sure what to do, and for 2/ I give below >> what I am doing at the moment. To be frank, it looks quite ugly >> (mainly because I am a bad programmer and don't know so much about >> python/matplotlib). >> >> I got inspired by cm and colors.py and Midas lut >> but really this is probably not the way to go. >> In order to change the lut I just then do: >> >> lut('mylut') >> >> where 'mylut.lasc' is then the ascii file where the 256 colours are >> given in 3 columns >> (R G B) of 256 rows >> >> The problem is that since I do not have the corresponding segmented >> array for each >> lut (and I don't want it to be that way) I need to define a ''dummy'' >> array. >> Then each time I use imshow I must reload the lut (otherwise it uses >> this dummy segmented >> array which is here a gray lut). >> >> I am not sure this is all clear, but basically what I am trying to do >> here is to just >> answer questions 1, 2, 3 above and below is an ugly solution for 2 >> (but incomplete). >> > > I think it is important to realize that you don't need to base it on > the existing colormapping mechanism, you just need to duplicate the > interface of colormaps, namely that it has N, and name attributes, and > that when the object is called with an array or scalar as an argument, > it will return the appropriate array (or tuple) as the result. How you > convert the array to rgba values is entirely up to you. But I think > there is enough similarity to what LinearSegmentColormap that > effectively its __call__ method can be resused without changed. You > would only override the __init__ to create the _red_lut, > _green_lut, _blue_lut attribute directly from array arguments (if I > remember what MIDAS does; it's been nearly 20 years since I've used it!). > > That is something like this (untested, untried!) > > class ArrayColormap(LinearSegmentColormap): > """ really, it seems that linear should inherit from Array > instead!""" def __init__(name, r,g,b): > """create color map from supplied r,g,b arrays""" > # put checks on r,g,b arrays here... > self._red_lut = r > self._green_lut = g > self._blue_lut = b > self.N = len(r) > self.name = name > > This is something we should add but you can try this in the meantime. > > The second part is how to set the lut to this. You can provide the new > colormap instance as a keyword (cmap) argument to imshow or figimage. > But I understand you would like a functional way to update an existing > display. There doesn't appear to be a function to do this, but a new > one is easily defined. Something like this ought to work (again > untested, and again, we should supply this in the next version) > > from > def loadcm(cm): > """change the default colormap to cm""" > rc('image', cmap='yourcmname') > im = gci() > if im is not None: > im.set_cmap(cm) > draw_if_interactive() > > But the problem with this is that default mechanism won't work since > this eventually calls cm.get_cmap, which then looks for the named cm > in the cm.datad array to construct a LinearSegmentedColormap instance. > I think the solution here may need to have some sort of caching > mechanism so that user defined colormaps can be used as a default > (perhaps John can think of some other mechanism). > > I agree that it should be simple to define your own on the fly and be > able to use these. So we'll see how this is best handled. > > I'm not sure what you mean by 3. If you are changing the lut (i.e., > which colors map to which image intensity levels, the rescaling the > image is required when displaying it (in the "old days" when image > displays were only 8-bit and had hardware luts, one didn't have to do > that). If all you mean is that you already had transformed the data to > log format but want to show the lut as though the data were linearly > displayed, I suppose one would display a colorbar where the > intensities were suitably transformed from a linear ramp. But please > elaborate. > > Perry > > > > > -- =============================================================== Observatoire de Lyon ems...@ob... 9 av. Charles-Andre tel: +33 4 78 86 83 84 69561 Saint-Genis Laval Cedex fax: +33 4 78 86 83 86 France http://www-obs.univ-lyon1.fr/eric.emsellem =============================================================== |