On 09/02/2010 01:21 PM, Benjamin Root wrote: > On Thu, Sep 2, 2010 at 3:51 PM, Ryan May <rma...@gmail.com > <mailto:rma...@gmail.com>> wrote: > > On Sep 2, 2010, at 14:14, Benjamin Root <ben.r...@ou.edu > <mailto:ben.r...@ou.edu>> wrote: > > > There was a bug report recently (not to the mailing list) where > the reporter noted that if an Axes3D was created using the > fig.add_subplot(111, projection='3d') or fig.gca(projection='3d'), > then you can not clear the figure using fig.clf(). Doing so causes > an exception to be thrown. > > > > Tracing down the problem revealed that the Axes3D object was > added twice to the figure's self.axes, but exists only once in > self._axstack. So, when looping through self.axes, a delete is > attempted on an axes that no longer exists in the stack. > > > > I traced down the cause for why the axes is added twice. Because > of how Axes3D used to be attached to a figure (and is still valid), > the __init__() function for Axes3D calls figure.add_axes(self) on > its own. This initialization is done after the check in add_subplot > to see if the axes exists already in the figure. So, add_subplot > then adds the axes without knowing that it already happened. > > > > I think there are multiple issues here. Primarially, there is > the issue that Axes3D is attaching itself to a figure. However, in > the interest of backwards-compatibility, we can't just fix this > outright. There is also the issue that there are multiple places in > the Figure class that are adding axes to the figure object. > Ideally, shouldn't we have a single function that performs proper > checks and adds an axes? Then that function should be used in the > other class functions to perform this action. In my opinion, there > is too much duplicated code here. > > I agree the duplicated code should be eliminated. Depending on how > complex it would be to clean that up and not break existing code, > could we in the short term make use of sets to eliminate duplicates? > > Ryan > > > I am not exactly sure how possible that would be. I am not exactly sure > I understand the rationale behind the current implementation. There is > a dictionary self._seen that stores key/axes pairs, a self.axes list > storing the axes, and a self._axstack Stack (from cbook, I believe) that > also contains the axes. > > I think I understand the purpose for each container by itself, but not > for having all three together at the same time. At the very least, > maybe we can eliminate the list container? I think the difficulty there > would be with clearing the stack properly.
You can't just blow away self.axes, because that is a public interface, and a convenient one. Maybe self.axes needs to be an object that can behave like a list, to preserve the public interface, but that underneath has the mechanisms required for the functionality now provided by self._seen and self._axstack, so that they can be eliminated. Eric > > Ben Root > ------------------------------------------------------------------------------ This SF.net Dev2Dev email is sponsored by: Show off your parallel programming skills. Enter the Intel(R) Threading Challenge 2010. http://p.sf.net/sfu/intel-thread-sfd _______________________________________________ Matplotlib-devel mailing list Matplotlib-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-devel