You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(33) |
Dec
(20) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(7) |
Feb
(44) |
Mar
(51) |
Apr
(43) |
May
(43) |
Jun
(36) |
Jul
(61) |
Aug
(44) |
Sep
(25) |
Oct
(82) |
Nov
(97) |
Dec
(47) |
2005 |
Jan
(77) |
Feb
(143) |
Mar
(42) |
Apr
(31) |
May
(93) |
Jun
(93) |
Jul
(35) |
Aug
(78) |
Sep
(56) |
Oct
(44) |
Nov
(72) |
Dec
(75) |
2006 |
Jan
(116) |
Feb
(99) |
Mar
(181) |
Apr
(171) |
May
(112) |
Jun
(86) |
Jul
(91) |
Aug
(111) |
Sep
(77) |
Oct
(72) |
Nov
(57) |
Dec
(51) |
2007 |
Jan
(64) |
Feb
(116) |
Mar
(70) |
Apr
(74) |
May
(53) |
Jun
(40) |
Jul
(519) |
Aug
(151) |
Sep
(132) |
Oct
(74) |
Nov
(282) |
Dec
(190) |
2008 |
Jan
(141) |
Feb
(67) |
Mar
(69) |
Apr
(96) |
May
(227) |
Jun
(404) |
Jul
(399) |
Aug
(96) |
Sep
(120) |
Oct
(205) |
Nov
(126) |
Dec
(261) |
2009 |
Jan
(136) |
Feb
(136) |
Mar
(119) |
Apr
(124) |
May
(155) |
Jun
(98) |
Jul
(136) |
Aug
(292) |
Sep
(174) |
Oct
(126) |
Nov
(126) |
Dec
(79) |
2010 |
Jan
(109) |
Feb
(83) |
Mar
(139) |
Apr
(91) |
May
(79) |
Jun
(164) |
Jul
(184) |
Aug
(146) |
Sep
(163) |
Oct
(128) |
Nov
(70) |
Dec
(73) |
2011 |
Jan
(235) |
Feb
(165) |
Mar
(147) |
Apr
(86) |
May
(74) |
Jun
(118) |
Jul
(65) |
Aug
(75) |
Sep
(162) |
Oct
(94) |
Nov
(48) |
Dec
(44) |
2012 |
Jan
(49) |
Feb
(40) |
Mar
(88) |
Apr
(35) |
May
(52) |
Jun
(69) |
Jul
(90) |
Aug
(123) |
Sep
(112) |
Oct
(120) |
Nov
(105) |
Dec
(116) |
2013 |
Jan
(76) |
Feb
(26) |
Mar
(78) |
Apr
(43) |
May
(61) |
Jun
(53) |
Jul
(147) |
Aug
(85) |
Sep
(83) |
Oct
(122) |
Nov
(18) |
Dec
(27) |
2014 |
Jan
(58) |
Feb
(25) |
Mar
(49) |
Apr
(17) |
May
(29) |
Jun
(39) |
Jul
(53) |
Aug
(52) |
Sep
(35) |
Oct
(47) |
Nov
(110) |
Dec
(27) |
2015 |
Jan
(50) |
Feb
(93) |
Mar
(96) |
Apr
(30) |
May
(55) |
Jun
(83) |
Jul
(44) |
Aug
(8) |
Sep
(5) |
Oct
|
Nov
(1) |
Dec
(1) |
2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
(3) |
Sep
(1) |
Oct
(3) |
Nov
|
Dec
|
2017 |
Jan
|
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
|
Sep
(7) |
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
|
|
|
|
1
|
2
(2) |
3
(7) |
4
(3) |
5
(7) |
6
(18) |
7
(6) |
8
|
9
(1) |
10
(1) |
11
(1) |
12
|
13
(5) |
14
(2) |
15
(2) |
16
|
17
(2) |
18
|
19
|
20
|
21
|
22
(1) |
23
(2) |
24
(3) |
25
(6) |
26
(1) |
27
|
28
(8) |
29
(9) |
30
(3) |
31
(4) |
|
|
|
|
|
On Tuesday, October 25, 2011, Daniel Hyams <dh...@gm...> wrote: > For small bugfixes, am I supposed to fork from v1.1.x, or master? > V1.1.x is the maintenance branch. Master is for new features. When bugfixes are made and merged to v1.1.x, we then merge it to master. Ben Root
For small bugfixes, am I supposed to fork from v1.1.x, or master? -- Daniel Hyams dh...@gm...
Daniel - Yes that works. In my case - I hate to edit any existing third party code bases - or it bites me later when I upgrade. For now - I simply do my own dead reference clean up externally when doing the deletes. Really, that would be the same as just doing a disconnect - but for other reasons (not worth going into detail here) - I prefer deleting and not having to know all of the connection points. My solution ensures that the dead references aren't around later. I mainly wanted to get it out into the devel community - get smart eyeballs on it - and hope that it gets addresses in a future release. It will likely be a fairly straightforward fix - as you show.
I've run into this same issue in the past, and have it "fixed" in my own local copy of matplotlib. I just placed a check to make sure that cid actually was in the callbacks for s before deleting it. That is quite possibly a band-aid; I never looked far enough in to see. But it is possibly another way of fixing the problem. def process(self, s, *args, **kwargs): """ process signal *s*. All of the functions registered to receive callbacks on *s* will be called with *\*args* and *\*\*kwargs* """ if s in self.callbacks: for cid, proxy in self.callbacks[s].items(): # Clean out dead references if proxy.inst is not None and proxy.inst() is None: if cid in self.callbacks[s]: #<------- here del self.callbacks[s][cid] else: proxy(*args, **kwargs) On Tue, Oct 25, 2011 at 1:09 PM, <to...@i3...> wrote: > Here is a bit more detail and a simple example. > > The example below places red squares in an axes. When the user clicks on an existing red square - another square is created and added. When the user hits any key a square is deleted from the axes. The error is triggered by clicking on the red square and then hitting any key, and then clicking a red square again. > > Diagnosis: > By monitoring cbook.py line 235 and cbook.py line 263 it can be seen that after the second mouse click (following one of the squares being deleted), that the process() function builds a loop and begins handling the button press callbacks. Note that there is a dead reference coming later in this list. The first callback involves another square being created and the connect() method being called. In the connect() call - the dead reference is deleted from the callback list. Now upon returning to the process() callback this dead reference is no longer in the callback list and a Key Exception is triggered once it gets to it in the loop. > > Problem: > There are two locations where dead references are cleared from the callback list. When these loops get intermingled - as the case with a callback leading to another connect mid-loop - the exception occurs when both loops attempt to delete the dead reference. > > Possible Solutions: > 1. Trap the KeyException at the point of attempting to delete it from the list in both places. > > 2. Place the dead reference check and deletion within a single method ... and perform this check at beginning of the process() and connect() methods before processing callbacks. > > > Sample Code > -------------------- > > import matplotlib > matplotlib.use('WXAGG') > > from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg > from matplotlib.pyplot import Figure, Axes, Rectangle > > import wx > import random > > class SquareManager(object): > def __init__(self, axes): > self.axes = axes > self.canvas = axes.figure.canvas > self.squares = [] > self.last_x = 0 > > self.canvas.mpl_connect('key_press_event', self.on_key_press) > > def add_square(self): > self.last_x += .1 > s = Square(self, self.axes, [self.last_x, .4], > .05, .05, facecolor='red', edgecolor='black') > self.squares.append(s) > self._refresh() > > def on_key_press(self, evt): > if len(self.squares) == 0: return > > # delete the first square - results in no error > # self.squares[0].remove() > # del self.squares[0] > > # delete the last square - results in the error > self.squares[-1].remove() > del self.squares[-1] > > self._refresh() > > def _refresh(self): > self.canvas.draw() > > > class Square(Rectangle): > def __init__(self, manager, axes, *args, **kwds): > Rectangle.__init__(self, *args, **kwds) > axes.add_patch(self) > > self.manager = manager > axes.figure.canvas.mpl_connect('button_press_event', self.selected) > > def selected(self, evt): > within, _ = self.contains(evt) > if within: > self.manager.add_square() > > > app = wx.PySimpleApp() > frame = wx.Frame(None) > fig = Figure() > canvas = FigureCanvasWxAgg(frame, -1, fig) > a = Axes(fig, [.1, .1, .8, .8]) > fig.add_axes(a) > > sm = SquareManager(a) > sm.add_square() > > frame.Show() > app.MainLoop() > > > # To demonstrate the error: > # > # 1. click on red sqaure > # 2. press any key > # 3. click on red sqaure again > > > > > > > > > > ------------------------------------------------------------------------------ > The demand for IT networking professionals continues to grow, and the > demand for specialized networking skills is growing even more rapidly. > Take a complimentary Learning@Cisco Self-Assessment and learn > about Cisco certifications, training, and career opportunities. > http://p.sf.net/sfu/cisco-dev2dev > _______________________________________________ > Matplotlib-devel mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-devel > -- Daniel Hyams dh...@gm...
Here is a bit more detail and a simple example. The example below places red squares in an axes. When the user clicks on an existing red square - another square is created and added. When the user hits any key a square is deleted from the axes. The error is triggered by clicking on the red square and then hitting any key, and then clicking a red square again. Diagnosis: By monitoring cbook.py line 235 and cbook.py line 263 it can be seen that after the second mouse click (following one of the squares being deleted), that the process() function builds a loop and begins handling the button press callbacks. Note that there is a dead reference coming later in this list. The first callback involves another square being created and the connect() method being called. In the connect() call - the dead reference is deleted from the callback list. Now upon returning to the process() callback this dead reference is no longer in the callback list and a Key Exception is triggered once it gets to it in the loop. Problem: There are two locations where dead references are cleared from the callback list. When these loops get intermingled - as the case with a callback leading to another connect mid-loop - the exception occurs when both loops attempt to delete the dead reference. Possible Solutions: 1. Trap the KeyException at the point of attempting to delete it from the list in both places. 2. Place the dead reference check and deletion within a single method ... and perform this check at beginning of the process() and connect() methods before processing callbacks. Sample Code -------------------- import matplotlib matplotlib.use('WXAGG') from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg from matplotlib.pyplot import Figure, Axes, Rectangle import wx import random class SquareManager(object): def __init__(self, axes): self.axes = axes self.canvas = axes.figure.canvas self.squares = [] self.last_x = 0 self.canvas.mpl_connect('key_press_event', self.on_key_press) def add_square(self): self.last_x += .1 s = Square(self, self.axes, [self.last_x, .4], .05, .05, facecolor='red', edgecolor='black') self.squares.append(s) self._refresh() def on_key_press(self, evt): if len(self.squares) == 0: return # delete the first square - results in no error # self.squares[0].remove() # del self.squares[0] # delete the last square - results in the error self.squares[-1].remove() del self.squares[-1] self._refresh() def _refresh(self): self.canvas.draw() class Square(Rectangle): def __init__(self, manager, axes, *args, **kwds): Rectangle.__init__(self, *args, **kwds) axes.add_patch(self) self.manager = manager axes.figure.canvas.mpl_connect('button_press_event', self.selected) def selected(self, evt): within, _ = self.contains(evt) if within: self.manager.add_square() app = wx.PySimpleApp() frame = wx.Frame(None) fig = Figure() canvas = FigureCanvasWxAgg(frame, -1, fig) a = Axes(fig, [.1, .1, .8, .8]) fig.add_axes(a) sm = SquareManager(a) sm.add_square() frame.Show() app.MainLoop() # To demonstrate the error: # # 1. click on red sqaure # 2. press any key # 3. click on red sqaure again
Ben: In current versions of matplotlib, the double click event is always just bound to the same handler as a single press. Such as the following code in backends/backend_wx.py: bind(self,wx.EVT_LEFT_DOWN,self._onLeftButtonDown) bind(self,wx.EVT_LEFT_DCLICK,self._onLeftButtonDown) bind(self,wx.EVT_LEFT_UP,self._onLeftButtonUp) so when someone double clicks on a canvas, the events sent would be (except in the case of gtk*) DOWN, UP, DOWN, UP. If a new event is created for the double click, the sequence of events generated would be DOWN,UP,DCLICK,UP. If you use a flag with in MouseEvent to signify the double click, the sequence of events would be DOWN,UP,DOWN.DCLICK,UP basically. This means that old code that relies on double clicks generating a DOWN event would still work, and newer code that wants to use double clicks need only query the MouseEvent.dblclick flag to see if a press was a double click or not. * for gtk, the event sequence for a double click is currently DOWN,UP,DOWN,DOWN,UP. That's the only backend that I've seen that does it this way. With the patch, the event sequence would be DOWN,UP,DOWN,DOWN.DCLICK,UP. On Sun, Oct 23, 2011 at 9:13 PM, Benjamin Root <ben...@ou...> wrote: > > > On Sunday, October 23, 2011, Daniel Hyams <dh...@gm...> wrote: >> I added double click support in, here in the following issue report: >> >> https://github.com/matplotlib/matplotlib/issues/550 >> >> I did use the extra flag in MouseEvent, but I can change this to a >> separate event if all think that it is appropriate; I still favor the >> flag for backwards compatibility. All backends are done except for >> cocoagg; see the issue report above for details. > > Thanks, I will look deeper into it tommorow. I am curious about what you > mean by backwards compatibility? How do you see having a new event type > cause issues? > > Ben Root > -- Daniel Hyams dh...@gm...
On Sunday, October 23, 2011, Daniel Hyams <dh...@gm...> wrote: > I added double click support in, here in the following issue report: > > https://github.com/matplotlib/matplotlib/issues/550 > > I did use the extra flag in MouseEvent, but I can change this to a > separate event if all think that it is appropriate; I still favor the > flag for backwards compatibility. All backends are done except for > cocoagg; see the issue report above for details. Thanks, I will look deeper into it tommorow. I am curious about what you mean by backwards compatibility? How do you see having a new event type cause issues? Ben Root
I added double click support in, here in the following issue report: https://github.com/matplotlib/matplotlib/issues/550 I did use the extra flag in MouseEvent, but I can change this to a separate event if all think that it is appropriate; I still favor the flag for backwards compatibility. All backends are done except for cocoagg; see the issue report above for details. On Sat, Oct 22, 2011 at 10:57 PM, Benjamin Root <ben...@ou...> wrote: > > > On Saturday, October 22, 2011, Daniel Hyams <dh...@gm...> wrote: >> matplotlib doesn't support double clicks, and I was wondering if that >> was a design decision, or something that had been relegated to the "to >> do" box for someday. Hoping that it was still in the "todo" box, I >> think I can put most of it in without too much trouble, and supply you >> with a patch. >> >> The changes would be: >> 1) an extra flag MouseEvent, so that in a button_press_event >> handler, you can can tell if the press was a result of a double click >> or not, and >> 2) code in the backends to catch and set the double click flag properly >> >> I looked through the backends, and it was clear what to do in order to >> support double clicks for all but backend_macosx.py. I might be able >> to deduce what to do there, but will likely need some support from >> someone in order to get that one done. >> >> To support the double clicks, I would rather not create a new event >> like 'button_doubleclick_event', for backwards compatibility. I >> believe that if we just stick with 'button_press_event' and set an >> extra flag within the MouseEvent, any existing mpl code will still >> work properly, because the normal sequence of events on a double click >> are; DOWN, UP, DBLCLICK, UP. In current versions of matplotlib, the >> DBLCLICK event is treated as a DOWN, and the strategy of just adding a >> extra flag in MouseEvent would mean that existing mpl code would still >> see the double click event as a DOWN. >> >> Anyway, I want to "throw a feeler" out there, and ask if the patch >> would be accepted were I to go ahead and do it. I didn't want to spend >> the time working on it if a decision had already been made a while >> back to not ever support double clicks. >> > > My vote would be yes, but I think i would want it as a separate event. > Consider some of the widgets like lasso and the zoom bbox. If one were to > attach a button_press_event for the purpose of detecting double clicks, I > would imagine that there may exist conflicts (or those widget codes would > have to be adjusted to exclusively respond only to single clicks). Would > existing widgets also fire even if a double-click occured? > > My 2 cents, > Ben Rootl -- Daniel Hyams dh...@gm...
On Saturday, October 22, 2011, Daniel Hyams <dh...@gm...> wrote: > matplotlib doesn't support double clicks, and I was wondering if that > was a design decision, or something that had been relegated to the "to > do" box for someday. Hoping that it was still in the "todo" box, I > think I can put most of it in without too much trouble, and supply you > with a patch. > > The changes would be: > 1) an extra flag MouseEvent, so that in a button_press_event > handler, you can can tell if the press was a result of a double click > or not, and > 2) code in the backends to catch and set the double click flag properly > > I looked through the backends, and it was clear what to do in order to > support double clicks for all but backend_macosx.py. I might be able > to deduce what to do there, but will likely need some support from > someone in order to get that one done. > > To support the double clicks, I would rather not create a new event > like 'button_doubleclick_event', for backwards compatibility. I > believe that if we just stick with 'button_press_event' and set an > extra flag within the MouseEvent, any existing mpl code will still > work properly, because the normal sequence of events on a double click > are; DOWN, UP, DBLCLICK, UP. In current versions of matplotlib, the > DBLCLICK event is treated as a DOWN, and the strategy of just adding a > extra flag in MouseEvent would mean that existing mpl code would still > see the double click event as a DOWN. > > Anyway, I want to "throw a feeler" out there, and ask if the patch > would be accepted were I to go ahead and do it. I didn't want to spend > the time working on it if a decision had already been made a while > back to not ever support double clicks. > My vote would be yes, but I think i would want it as a separate event. Consider some of the widgets like lasso and the zoom bbox. If one were to attach a button_press_event for the purpose of detecting double clicks, I would imagine that there may exist conflicts (or those widget codes would have to be adjusted to exclusively respond only to single clicks). Would existing widgets also fire even if a double-click occured? My 2 cents, Ben Rootl
matplotlib doesn't support double clicks, and I was wondering if that was a design decision, or something that had been relegated to the "to do" box for someday. Hoping that it was still in the "todo" box, I think I can put most of it in without too much trouble, and supply you with a patch. The changes would be: 1) an extra flag MouseEvent, so that in a button_press_event handler, you can can tell if the press was a result of a double click or not, and 2) code in the backends to catch and set the double click flag properly I looked through the backends, and it was clear what to do in order to support double clicks for all but backend_macosx.py. I might be able to deduce what to do there, but will likely need some support from someone in order to get that one done. To support the double clicks, I would rather not create a new event like 'button_doubleclick_event', for backwards compatibility. I believe that if we just stick with 'button_press_event' and set an extra flag within the MouseEvent, any existing mpl code will still work properly, because the normal sequence of events on a double click are; DOWN, UP, DBLCLICK, UP. In current versions of matplotlib, the DBLCLICK event is treated as a DOWN, and the strategy of just adding a extra flag in MouseEvent would mean that existing mpl code would still see the double click event as a DOWN. Anyway, I want to "throw a feeler" out there, and ask if the patch would be accepted were I to go ahead and do it. I didn't want to spend the time working on it if a decision had already been made a while back to not ever support double clicks. -- Daniel Hyams dh...@gm...
moved from matplotlib-users: http://sourceforge.net/mailarchive/forum.php?thread_name=CAN06%3DCx2zgh8YrnF2WRaJ%3D0E8i3ROLdYW4VuurtqKrx3mdkeEg%40mail.gmail.com&forum_name=matplotlib-users On 10/22/2011 09:31 AM, Friedrich Romstedt wrote: > 2011年10月21日 Friedrich Romstedt<fri...@gm...>: >> I will try to dig out that emails. > > Did that, the email I meant dates back to 10 November 2010! Here's the snippet: > > <snippet> > > (Ben Root): >> I am curious, could this approach you have done be generalized to any sort >> of color transformation? Admittedly, a gray mode is probably the most >> common request, but what if someone wants a different transformation? Maybe >> even apply a filter that would produce sepia colors, or high-contrast >> colors, or a different grayscale transform? Heck, I could imagine a use >> where a user might want to do a color substitution? > > Oh Yes, this is *ealily* possible. The new framework in the > ColorConverter class just uses a filter function, if we want to see it > like that, already. It's just the apply_rc_gray_setting() function or > sth like that. If you want to, you can try to add the functionality. > But we should discuss beforehand how to design it. There are several > possibilites. In fact, I like this filter function quite a lot! > > 1) Hardcoding other filters in ColorConverter (what a decent name!), > and switching them on or off > 2) Inserting filters as functions on runtime into the ColorConverter > instance, some hooking mechanism > 3) Providing a dedicated Filter class, that can be fed to > set_filter() instead of set_gray(). This I like best. > > I will, when i find some time, first implement the propagation of gray > settings by allowing objects in set_gray(). Might be a good time to > rename it to set_filter() right away, or maybe not do it, if > set_gray() goes in, and expects a bool, it might break compat when > changing the argument spec later. So later set_gray() would just call > set_filter() or add_filter() or whatever. > > </snippet> > > So the filter idea was Ben's idea. I still like idea (3) for the > design best. I will check if it is possible to inject the filter code > into the renderer framework, since all colour settings arguments > somewhen flow into a call into the renderer. Pro: No rcParams > addition necessary, no modification of the peculiar colors.py > ColorConverter framework necessary, just leaving those things > untouched and hence no worries and headaches about them. No disabling > of higher-level caching and at the same time negligible small impact > if there is no filter active. Con: I don't know yet if it works. I > vaguely remember there were some problems when I checked that > possibility last time (with pixmaps or something like that). I think > I will find out soon enough. > > Eric, Ben, do you think we should go off-list with this now? I would > prefer on-list now. There might be people following but not > responding. > > Friedrich Friedrich, The matplotlib-devel list is really the place for this, and I think that it will be very helpful to move the discussion there. So, I am doing that now by simply addressing this to matplotlib-devel and removing -users from the address list. Eric
Another common solution to this problem is to copy the list of callbacks before iterating over it. Having a simple example would be helpful here so we can experiment with these alternate approaches. Mike On 10/16/2011 09:04 PM, to...@i3... wrote: > Within matplotlib.cbook.CallbackRegistry both the connect() and process() methods check for dead references when called. If a reference is dead it deletes it from the callback list. > > I have found a situation where this presents a problem. > > First, a "button_press_event" calls the process method() which begins a loop over all of the callback items for this event. One of these items is a dead reference but appears late in the list. The first callback within the loop creates a new connection and calls the connect method. During this connect call the dead reference is deleted from the callback list. Then when it gets back to the loop within the process method the callback no longer exists in the list it is iterating over and there is an error thrown when it tries to delete the dead reference for the second time. > > The problem is coordination between these two places that both could potentially delete a dead reference to a BoundMethodProxy. In my case, because one loop has started ... the attempt is made twice ... and obviously the second results in an error. > > I could put together a simple example if needed to demonstrate the error. > > I think the easy way to handle would be to first call a method who's job is only to delete dead references. Then each method could call this first before handling the callbacks. This would keep the intermingling of the two loops that both check for dead references. > > Another (potentially more obscure approach) could be to just wrap the delete with a try/except - but this suffers from not fixing a bit of a design problem. > > There are likely more approaches to solving. > > > > ------------------------------------------------------------------------------ > All the data continuously generated in your IT infrastructure contains a > definitive record of customers, application performance, security > threats, fraudulent activity and more. Splunk takes this data and makes > sense of it. Business sense. IT sense. Common sense. > http://p.sf.net/sfu/splunk-d2d-oct > _______________________________________________ > Matplotlib-devel mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
Within matplotlib.cbook.CallbackRegistry both the connect() and process() methods check for dead references when called. If a reference is dead it deletes it from the callback list. I have found a situation where this presents a problem. First, a "button_press_event" calls the process method() which begins a loop over all of the callback items for this event. One of these items is a dead reference but appears late in the list. The first callback within the loop creates a new connection and calls the connect method. During this connect call the dead reference is deleted from the callback list. Then when it gets back to the loop within the process method the callback no longer exists in the list it is iterating over and there is an error thrown when it tries to delete the dead reference for the second time. The problem is coordination between these two places that both could potentially delete a dead reference to a BoundMethodProxy. In my case, because one loop has started ... the attempt is made twice ... and obviously the second results in an error. I could put together a simple example if needed to demonstrate the error. I think the easy way to handle would be to first call a method who's job is only to delete dead references. Then each method could call this first before handling the callbacks. This would keep the intermingling of the two loops that both check for dead references. Another (potentially more obscure approach) could be to just wrap the delete with a try/except - but this suffers from not fixing a bit of a design problem. There are likely more approaches to solving.
On Fri, Oct 14, 2011 at 9:11 PM, Daniel Hyams <dh...@gm...> wrote: > This could be intentional...I don't know much about the history of > matplotlib, so it's hard to guess at these things. Anyway, the figure > container does not care about the "animated" state of its artists when it > does its drawing. > To fix this, in the Figure.draw routine (in figure.py), add the following > line just before dsu.sort(): > dsu = [x for x in dsu if not x[1].im_self.get_animated()] This looks like it might fail for composite images, where the draw method is not an Artist method, so im_self will not be defined. Eg in figimage_demo.py where "fig.suppressComposite = False" since the draw method is the local function "draw_composite'. To handle this case as well, I submitted a slightly more verbose pull request at https://github.com/matplotlib/matplotlib/pull/528 JDH
This could be intentional...I don't know much about the history of matplotlib, so it's hard to guess at these things. Anyway, the figure container does not care about the "animated" state of its artists when it does its drawing. To fix this, in the Figure.draw routine (in figure.py), add the following line just before dsu.sort(): dsu = [x for x in dsu if not x[1].im_self.get_animated()] -- Daniel Hyams dh...@gm...
On Fri, Oct 14, 2011 at 6:30 AM, Wesley Emeneker <Wes...@oi...> wrote: > Attached is patch that moves > #include <cstdlib> > to before > #include <cmath> > > The Portland group compiler (v 11.8) won't build ttconv/pprdrv_tt2.cpp with > the original ordering. > This is most likely a compiler bug, but changing the include order seems > pretty harmless. > > Thanks for the great tool. > I love matplotlib. > Thanks for the report -- filed as issue https://github.com/matplotlib/matplotlib/issues/526
Attached is patch that moves #include <cstdlib> to before #include <cmath> The Portland group compiler (v 11.8) won't build ttconv/pprdrv_tt2.cpp with the original ordering. This is most likely a compiler bug, but changing the include order seems pretty harmless. Thanks for the great tool. I love matplotlib. Wesley -- Wesley Emeneker, Research Scientist The Partnership for an Advanced Computing Environment Georgia Institute of Technology 404.385.2303 Wes...@oi... http://pace.gatech.edu
Ah yes, I forget :/ I was focused on images as being "pure" things that should be displayed, and forgot about the image processing angle. So would the solution be a keyword argument that tells imshow/BboxImage and friends not to interpolate when at native resolution, which is set to the current behavior as default? If that's not an acceptable solution, I can just leave the patch in my own personal code and not worry about any further...I thought that I was fixing a bug there :) I guess the main difference is whether the image is treated as sacred and should be displayed perfectly when possible, versus the ability to modify the picture on purpose via the interpolations, for whatever reason the user wants. Understandably, matplotlib has taken the latter approach, because the context has always been (as far as I can tell from the examples) displaying the pixels for a scientific purpose. However, when you want to display an image for a annotational type purpose, the former approach should be taken, in my opinion. On Thu, Oct 13, 2011 at 11:13 AM, John Hunter <jd...@gm...> wrote: > On Thu, Oct 13, 2011 at 10:06 AM, Daniel Hyams <dh...@gm...> wrote: > > > Isn't the purpose of interpolation to handle situations where the image > is > > being displayed at a different size than its native resolution? It seems > > Not solely, it can also be used to do local average of noisy images to > get a smoother view, eg bilinear or bicubic averaging of neighboring > pixels. > -- Daniel Hyams dh...@gm...
On Thu, Oct 13, 2011 at 10:06 AM, Daniel Hyams <dh...@gm...> wrote: > Isn't the purpose of interpolation to handle situations where the image is > being displayed at a different size than its native resolution? It seems Not solely, it can also be used to do local average of noisy images to get a smoother view, eg bilinear or bicubic averaging of neighboring pixels.
> > > imshow() does take an "interpolation" kwarg, where you can specify > "nearest" for pre v1.1.0 versions and "none" (not None) in the recent > release. "nearest" would be close to what you want, while "none" is exactly > what you want. > > Personally, I don't think it would be a good idea to automatically turn > interpolation off on such a specific set of conditions, but I could be > wrong. I would rather have the user explicitly state their interpolation > intentions. > > Ben Root Hello Ben, Isn't the purpose of interpolation to handle situations where the image is being displayed at a different size than its native resolution? It seems appropriate to me to turn interpolation off in such a case. Just some context of what I was up to when I ran into this one....I'm trying to allow the user to paste images (either from file or clipboard) onto a matplotlib canvas and be able to drag and resize them, very similar to the way powerpoint works. So I wanted to work with the appropriate image object in matplotlib, and BboxImage was the best I found after digging in the code for a bit; imshow() is too tied to the axis....these are supposed to be just free floating images. What I ran into was that, on initial paste (where I am sizing the BboxImage the same width/height as the incoming picture), the image was very blurry (because of the interpolation). I still want the interpolation on so that the image looks nice when it is resized by the user with the grab handles, but in the specific case where no interpolation is needed, this patch turns it off. The pasting/dragging/resizing has actually turned out pretty well...once I get it cleaned up and working how I want it to, I'll submit it to you guys for inclusion into matplotlib if you want it. I was hoping to formulate it as a mixin that will work for any artist (not just BboxImage) within reasonable limits. -- Daniel Hyams dh...@gm...
On Thursday, October 13, 2011, Daniel Hyams <dh...@gm...> wrote: > I was playing around with images.BboxImage, and found that if I displayed, say a 100x100 image at its native resolution (exactly 100x100 pixels on the plotting window), it was blurred. This is because of the interpolation jumping in and interpolating when it is not needed. > This might not be the best way to fix, but it does work....in matplotlib 1.0.0, it is image.py around line 1102 (this is BboxImage.make_image). Just after numrows and numcols is set in that routine, do > if (r-l) == numcols and (t-b) == numrows: > im.set_interpolation(0) > As you can see, all this does is just flip the interpolation off if the size of the image is the same size that it is about to be rendered as...and the regular interpolation is used otherwise. > > I do apologize for the lack of a proper patch, but for little things like this I think a word description works as well or better; I need to sit down and both learn git and set of a development environment for matplotlib, but after reading through the docs on the web site about it, decided that would take me more time than I had at the moment. > > In context: > def make_image(self, renderer, magnification=1.0): > if self._A is None: > raise RuntimeError('You must first set the image array or the image attribute') > if self._imcache is None: > if self._A.dtype == np.uint8 and len(self._A.shape) == 3: > im = _image.frombyte(self._A, 0) > im.is_grayscale = False > else: > if self._rgbacache is None: > x = self.to_rgba(self._A, self._alpha) > self._rgbacache = x > else: > x = self._rgbacache > im = _image.fromarray(x, 0) > if len(self._A.shape) == 2: > im.is_grayscale = self.cmap.is_gray() > else: > im.is_grayscale = False > self._imcache = im > if self.origin=='upper': > im.flipud_in() > else: > im = self._imcache > # image input dimensions > im.reset_matrix() > im.set_interpolation(self._interpd[self._interpolation]) > > > im.set_resample(self._resample) > l, b, r, t = self.get_window_extent(renderer).extents #bbox.extents > widthDisplay = (round(r) + 0.5) - (round(l) - 0.5) > heightDisplay = (round(t) + 0.5) - (round(b) - 0.5) > widthDisplay *= magnification > heightDisplay *= magnification > numrows, numcols = self._A.shape[:2] > > if (r-l) == numcols and (t-b) == numrows: # <----------------- add this > im.set_interpolation(0) #<-------------- and this > # resize viewport to display > rx = widthDisplay / numcols > ry = heightDisplay / numrows > #im.apply_scaling(rx*sx, ry*sy) > im.apply_scaling(rx, ry) > #im.resize(int(widthDisplay+0.5), int(heightDisplay+0.5), > # norm=self._filternorm, radius=self._filterrad) > im.resize(int(widthDisplay), int(heightDisplay), > norm=self._filternorm, radius=self._filterrad) > return im > > -- > Daniel Hyams > dh...@gm... > Daniel, imshow() does take an "interpolation" kwarg, where you can specify "nearest" for pre v1.1.0 versions and "none" (not None) in the recent release. "nearest" would be close to what you want, while "none" is exactly what you want. Personally, I don't think it would be a good idea to automatically turn interpolation off on such a specific set of conditions, but I could be wrong. I would rather have the user explicitly state their interpolation intentions. Ben Root
I was playing around with images.BboxImage, and found that if I displayed, say a 100x100 image at its native resolution (exactly 100x100 pixels on the plotting window), it was blurred. This is because of the interpolation jumping in and interpolating when it is not needed. This might not be the best way to fix, but it does work....in matplotlib 1.0.0, it is image.py around line 1102 (this is BboxImage.make_image). Just after numrows and numcols is set in that routine, do if (r-l) == numcols and (t-b) == numrows: im.set_interpolation(0) As you can see, all this does is just flip the interpolation off if the size of the image is the same size that it is about to be rendered as...and the regular interpolation is used otherwise. I do apologize for the lack of a proper patch, but for little things like this I think a word description works as well or better; I need to sit down and both learn git and set of a development environment for matplotlib, but after reading through the docs on the web site about it, decided that would take me more time than I had at the moment. In context: def make_image(self, renderer, magnification=1.0): if self._A is None: raise RuntimeError('You must first set the image array or the image attribute') if self._imcache is None: if self._A.dtype == np.uint8 and len(self._A.shape) == 3: im = _image.frombyte(self._A, 0) im.is_grayscale = False else: if self._rgbacache is None: x = self.to_rgba(self._A, self._alpha) self._rgbacache = x else: x = self._rgbacache im = _image.fromarray(x, 0) if len(self._A.shape) == 2: im.is_grayscale = self.cmap.is_gray() else: im.is_grayscale = False self._imcache = im if self.origin=='upper': im.flipud_in() else: im = self._imcache # image input dimensions im.reset_matrix() im.set_interpolation(self._interpd[self._interpolation]) im.set_resample(self._resample) l, b, r, t = self.get_window_extent(renderer).extents #bbox.extents widthDisplay = (round(r) + 0.5) - (round(l) - 0.5) heightDisplay = (round(t) + 0.5) - (round(b) - 0.5) widthDisplay *= magnification heightDisplay *= magnification numrows, numcols = self._A.shape[:2] if (r-l) == numcols and (t-b) == numrows: # <----------------- add this im.set_interpolation(0) #<-------------- and this # resize viewport to display rx = widthDisplay / numcols ry = heightDisplay / numrows #im.apply_scaling(rx*sx, ry*sy) im.apply_scaling(rx, ry) #im.resize(int(widthDisplay+0.5), int(heightDisplay+0.5), # norm=self._filternorm, radius=self._filterrad) im.resize(int(widthDisplay), int(heightDisplay), norm=self._filternorm, radius=self._filterrad) return im -- Daniel Hyams dh...@gm...
A new release of matplotlib is available for download at https://sourceforge.net/projects/matplotlib/files/matplotlib/matplotlib-1.1.0 There are lots of nifty new features like Sankey diagrams, an API for animations and movie making, enhanced 3D support, support for auto-layout of subplots with titles, xlabels and ylabels to prevent text from running off the edge of the figure (tight_layout), pyside supoprt, enhanced legends, and tons of other minor features and bug-fixes. See what's new at http://matplotlib.sourceforge.net/users/whats_new.html and the CHANGELOG at https://github.com/matplotlib/matplotlib/blob/v1.1.x/CHANGELOG and the commit history at https://github.com/matplotlib/matplotlib/commits/v1.1.x/ Please post issues on the github issue tracker and questions on the mailing list https://github.com/matplotlib/matplotlib/issues Thanks to all the matplotlib developers who contributed to this release, with special thanks to Michael Droettboom, Eric Firing, Benjamin Root, Jouni Seppänen, Kevin Davies and Jae-Joon Lee for lots of code contributions and bug fixes and to Christoph Gohlke and Russell Owen for the windows and OX X binary installers. JDH
...Forget about visiting local drugstores! Visit this on-line shop now! http://j13.free.fr/friends.page.php?atgoogle=73si5
Hi all, I'm writing here in the hopes that both the ubuntu packagers are on this list, and that we change things a bit in mpl to prevent this problem from happening. After a nasty debugging marathon with the IPython test suite failing on Ubuntu 11.10 beta -- see details at https://github.com/ipython/ipython/issues/823, I finally tracked the problem down to this little gem: amirbar[matplotlib-1.0.1.egg-info]> pwd /usr/share/pyshared/matplotlib-1.0.1.egg-info amirbar[matplotlib-1.0.1.egg-info]> cat entry_points.txt [nose.plugins] KnownFailure = matplotlib.testing.noseclasses:KnownFailure I'm not sure why the packagers decided to register this as a global plugin, but it makes a mess. You can read some of the details in the thread above if you're really interested. I've filed the ubuntu bug here: https://bugs.launchpad.net/ubuntu/+source/matplotlib/+bug/871176 But I suggest we actually *remove* this code from matplotlib altogether. In ipython we do carry a copy of the same code, but we load it very conditionally, only if numpy isn't found: https://github.com/ipython/ipython/blob/master/IPython/external/decorators/_numpy_testing_noseclasses.py This ensures we'll never collide with the 'real' version in numpy. For IPython, numpy isn't a dependency, so we have to do this. But mpl always has numpy around, so perhaps it would be better to simply use it from numpy? Cheers, f