From: John H. <jdh...@ac...> - 2004-04-29 15:36:32
|
>>>>> "Flavio" == Flavio Codeco Coelho <fcc...@fi...> writes: Flavio> Hi, Is there a way to get the output of a plot (the Flavio> bitmap) and assign it to a bitmap object such as wxBitmap Flavio> or wxImage? I know how to do this by saving the figure Flavio> and loading it to wxBitmap. But there must be a way to do Flavio> it directly. Does anyone know how to do this? Using the OO FigureCanvasWxAgg API, which I think you are using, you already have the canvas instance. The call to canvas.draw() sets the bitmap instance, which you can access as canvas.bitmap. So after any draw command canvas.bitmap is updated. You can take a look at matplotlib.backends.backend_wxagg.FigureCanvasWxAgg.draw to see how the backend is using agg to render, create a wxImage and wxBitmap. You can either use the result of these calls (canvas.bitmap) or just make them yourself in another part of your code. JDH |
From: Perry G. <pe...@st...> - 2004-04-29 15:51:32
|
> >>>>> "Flavio" == Flavio Codeco Coelho <fcc...@fi...> writes: > > Flavio> Hi, Is there a way to get the output of a plot (the > Flavio> bitmap) and assign it to a bitmap object such as wxBitmap > Flavio> or wxImage? I know how to do this by saving the figure > Flavio> and loading it to wxBitmap. But there must be a way to do > Flavio> it directly. Does anyone know how to do this? > > Using the OO FigureCanvasWxAgg API, which I think you are using, you > already have the canvas instance. The call to canvas.draw() sets the > bitmap instance, which you can access as canvas.bitmap. So after any > draw command canvas.bitmap is updated. > > You can take a look at > matplotlib.backends.backend_wxagg.FigureCanvasWxAgg.draw to see how > the backend is using agg to render, create a wxImage and wxBitmap. > You can either use the result of these calls (canvas.bitmap) or just > make them yourself in another part of your code. > > JDH > But it does make sense to have a general function to read out an AGG rendered buffer to a Numeric/numarray array doesn't it? Seems like another good thing to add to the list (unless one can do that already, I forget the details of using AGG by itself). Perry |
From: John H. <jdh...@ac...> - 2004-04-29 17:18:08
|
>>>>> "Perry" == Perry Greenfield <pe...@st...> writes: Perry> But it does make sense to have a general function to read Perry> out an AGG rendered buffer to a Numeric/numarray array Perry> doesn't it? Seems like another good thing to add to the Perry> list (unless one can do that already, I forget the details Perry> of using AGG by itself). You can do this with string methods already. The question is: is it worth adding a to_numerix and/or from_numerix method for performance and convenience to directly access the agg pixel buffer representing the entire figure canvas. The (smallish) downside of the latter is that currently backend_agg does not depend on Numeric/numarray at all. There are a couple of ways to go here and I think it would be useful to know how people would want to use this functionality. In the example below, I show how to get the agg pixel buffer as an rgb string and either convert it to an array or pass it to PIL. I need to add the tostring_rgba equivalent - I added tostring_rgba this as a helper for backend ps which doesn't need alpha. If all that is needed is a way to get at the contents as an array, then it may be enough to wrap the example code below in a helper function or appropriate class method. But if one wants to be able to directly manipulate the contents of the agg rgba pixel array using numeric and then pass this back to agg, more will be needed. So knowing what people need this for, and how critical performance issues will be in these cases, is important in deciding which tack to take. """ Use backend agg to access the figure canvas as an RGB string and then convert it to a Numeric array and pass the string it to PIL for rendering """ from matplotlib.matlab import * from matplotlib.backends.backend_agg import FigureCanvasAgg plot([1,2,3]) canvas = get_current_fig_manager().canvas agg = canvas.switch_backends(FigureCanvasAgg) agg.draw() s = agg.tostring_rgb() # get the width and the height to resize the matrix l,b,w,h = agg.figure.bbox.get_bounds() w, h = int(w), int(h) X = fromstring(s, UInt8) X.shape = h, w, 3 import Image im = Image.fromstring( "RGB", (w,h), s) im.show() |
From: Perry G. <pe...@st...> - 2004-04-29 17:51:03
|
John Hunter wrote: > You can do this with string methods already. The question is: is it > worth adding a to_numerix and/or from_numerix method for performance > and convenience to directly access the agg pixel buffer representing > the entire figure canvas. The (smallish) downside of the latter is > that currently backend_agg does not depend on Numeric/numarray at all. > > There are a couple of ways to go here and I think it would be useful > to know how people would want to use this functionality. In the > example below, I show how to get the agg pixel buffer as an rgb string > and either convert it to an array or pass it to PIL. I need to add > the tostring_rgba equivalent - I added tostring_rgba this as a helper > for backend ps which doesn't need alpha. > > If all that is needed is a way to get at the contents as an array, > then it may be enough to wrap the example code below in a helper > function or appropriate class method. But if one wants to be able to > directly manipulate the contents of the agg rgba pixel array using > numeric and then pass this back to agg, more will be needed. > > So knowing what people need this for, and how critical performance > issues will be in these cases, is important in deciding which tack to > take. > It's not a strong driver for us at the moment, but I agree that it depends on how people see using this capability. For our part (and this is just limited to my knee-jerk reaction, there may be other uses that I can't think of but others may) I would guess the most common use would be to create some sort of image with overlays (contours, legends, etc) that one wants to write out to one of the scientific data formats that are used to store scientific images. Normally these would be array-aware and so arrays make a good intermediary. Perhaps the values would be manipulated as well as arrays but that seems less likely. I'll see if I can conceive of any other uses. Saving memory copying doesn't seem to be that important for these sorts of uses since they would not be frequent, nor involve gigantic images that couldn't stand to be copied. An associated question is how one easily maps a monochromatic image that is displayed in matplotlib back into a monochromatic array. Normally it's going to be converted to rgba even if rgba is not really needed. Is there any simple way of mapping it back to intensity (histogram of the rgba values to determine if such a mapping exists?). Hmmm. Perry |
From: John H. <jdh...@ac...> - 2004-04-29 18:08:42
|
>>>>> "Perry" == Perry Greenfield <pe...@st...> writes: Perry> An associated question is how one easily maps a Perry> monochromatic image that is displayed in matplotlib back Perry> into a monochromatic array. Normally it's going to be Perry> converted to rgba even if rgba is not really needed. Is Perry> there any simple way of mapping it back to intensity Perry> (histogram of the rgba values to determine if such a Perry> mapping exists?). Hmmm. Well, assuming you passed it to matplotlib with no colormap, then a default intensity grayscale would be used. In that case, just build the rgb array as above using string methods and then take the r, g, or b slice out of it since they are all identical. If you passed in a colormap, you would need to invert the colormap, which would be relatively easy to provide in the colors.Colormap interface but I'm having trouble imagining why someone would want to do this. Both of these would be lossy, of course, eg if you started with an array of floats you would get back an array of UInt8s. Note agg comes with several helpful pixel converters functions: gray8, rgb565, rgb555, bgr24, bgr24, bgra32, abgr32, argb32, rgba32. Perhaps the best general solution is to define these as module constants and provide a single tostring method that takes one of these constants and returns the appropriate string representation. I can image that this would be useful both for backend agg and the image module. JDH |
From: Perry G. <pe...@st...> - 2004-04-29 18:35:13
|
John Hunter wrote: > Well, assuming you passed it to matplotlib with no colormap, then a > default intensity grayscale would be used. In that case, just build > the rgb array as above using string methods and then take the r, g, or > b slice out of it since they are all identical. > Yep, this is the simple case. > If you passed in a colormap, you would need to invert the colormap, > which would be relatively easy to provide in the colors.Colormap > interface but I'm having trouble imagining why someone would want to > do this. > Me too. (Well, I'm thinking of older displays that actually used color lookup tables. The image would be stored in the display buffer as 8-bit intensity, and displayed to the screen through a lookup color table. In that case one could manipulate the image display as a intensity image and expect to read it out as such while using whatever psychedelic color table one wanted to please their eyes. But that's rare these days.) > Both of these would be lossy, of course, eg if you started with an > array of floats you would get back an array of UInt8s. > Yep. > Note agg comes with several helpful pixel converters functions: gray8, > rgb565, rgb555, bgr24, bgr24, bgra32, abgr32, argb32, rgba32. Perhaps > the best general solution is to define these as module constants and > provide a single tostring method that takes one of these constants and > returns the appropriate string representation. I can image that this > would be useful both for backend agg and the image module. > Sounds reasonable. Perry |