Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Enh python repl rd2#4506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Enh python repl rd2#4506
Uh oh!
There was an error while loading.Please reload this page.
Conversation
The IPython hook we use in post_execute, not display.
If we do not have IPython, then the only hook I know of in the repl isthe display hook which is called when ever something is going to bedisplayed, not after the execution of the last command has finished (thereason it exists is to give users a chance to intercept and change thedisplay of the output, not as a generic call back as we were trying touse it). In this case register a callback on the `Figure` artist atcreation time to call `draw_idle` on the canvas if the Figure is stale.We are guaranteed to see this at least once when stale is flipped toTrue, but may see it more than once if other paths call `pchanged()`.Fortunately, `pchanged` is not widely used in the internal code base andeven if `draw_idle` is called multiple times, we should be able to counton the backends handling multiple draw_idle commands correctly.Closesmatplotlib#4504
Avoids a possibly un-needed re-draw.
👍 |
def auto_draw(fig): | ||
if fig.stale and matplotlib.is_interactive(): | ||
fig.canvas.draw_idle() | ||
figManager.canvas.figure.add_callback(auto_draw) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
should we record the callback id somewhere, maybe to make it possible to disable the auto_draw() if plt.ioff() is called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
As this is registered on a per-figure basis that gets a bit messy book keeping wise and would probably need to be pushed back up into Gcf which is more complicated than Ireally want to make this. I am happy to say that if youreally care about controlling ion/ioff, use IPython where we have better control of the hooks.
In the base case, all new figures will respect the setting, existing figures will respect the last setting which seems fair-ish.
I also don't see the use case for rapidly switching between ion/ioff.
Failures are pickles not being sanitized enough on the way out (the local function is not pickleable). Should probably fix that, but the faster solution is to move the |
I did a little quick testing, and it looks great! Is there any real disadvantage to making auto_redraw top-level? |
Nope, just me solving this in the first way that popped into my head on the train. I was thinking this was going to be a closure, but it is not. |
Not sure what is wrong with the build, it seems to build fine locally, but is stalling on travis. |
sorry ^doc build |
No that's puzzling. It looks like both jobs hung in or after the same example: examples/mplot3d/rotate_axes3d_demo |
now, that's interesting. rotate_axes3d_demo.py is a bit of an oddball. It and wire3d_animation_demo.py are the only two doc build examples that calls |
Ah, should try to run it locally with the rcparams that are used on Travis. On Tue, Jun 9, 2015, 10:57 Benjamin Rootnotifications@github.com wrote:
|
so, I am now very confused asno 3D things are working for me on master either: Traceback (mostrecentcalllast):File"/home/tcaswell/source/my_source/matplotlib/lib/matplotlib/backends/backend_qt5.py",line343,inresizeEventself.draw()File"/home/tcaswell/source/my_source/matplotlib/lib/matplotlib/backends/backend_qt5agg.py",line147,indrawFigureCanvasAgg.draw(self)File"/home/tcaswell/source/my_source/matplotlib/lib/matplotlib/backends/backend_agg.py",line475,indrawself.figure.draw(self.renderer)File"/home/tcaswell/source/my_source/matplotlib/lib/matplotlib/artist.py",line60,indraw_wrapperdraw(artist,renderer,*args,**kwargs)File"/home/tcaswell/source/my_source/matplotlib/lib/matplotlib/figure.py",line1122,indrawfunc(*args)File"/home/tcaswell/.virtualenvs/dd_3k/lib/python3.4/site-packages/mpl_toolkits/mplot3d/axes3d.py",line273,indrawax.draw(renderer)File"/home/tcaswell/.virtualenvs/dd_3k/lib/python3.4/site-packages/mpl_toolkits/mplot3d/axis3d.py",line264,indrawself.axes.transAxes.transform(peparray[0:2,0]))ValueError:Expected2-dimensionalarray,got1 |
and I am nowcompletely flumoxed. I have pulled out the values of This works In [28]:ax.transAxes.transform(np.array(dd[0:2,0]))Out[28]:array([67.42554669,57.0430007 ]) This fails: In [32]:a=ax.transAxes.transform(np.array(dd[0:2,0]))---------------------------------------------------------------------------ValueErrorTraceback (mostrecentcalllast)ValueError:Expected2-dimensionalarray,got1 This works: In [36]:a=ax.transAxes.transform([-0.07047539,-0.05412152]) This does not: In [35]:a=ax.transAxes.transform(np.array([-0.07047539,-0.05412152]))---------------------------------------------------------------------------ValueErrorTraceback (mostrecentcalllast)ValueError:Expected2-dimensionalarray,got1 and In [38]:a=ax.transAxes.transform(list(dd[0:2,0]))In [39]:a=ax.transAxes.transform(dd[0:2,0])---------------------------------------------------------------------------ValueErrorTraceback (mostrecentcalllast)ValueError:Expected2-dimensionalarray,got1In [40]: For those playing along at home: In [37]:ddOut[37]:array([[-0.07047539,0.01976701], [-0.05412152,-0.08365497], [-0.99055809,-1.03688574]]) and fig=plt.figure()ax=fig.add_subplot(111,projection='3d') |
Sorry, I hope no one wasted any time on this. The root cause seems to be crossed installations on my end, sorry for the noise. |
Removing the |
I still need to deal with@WeatherGod 's comment about the order of calling |
There is still one `draw_if_interactive` left in the `rcdefaults`call as the current scheme does not track when rcparams change.
@mdehoon,@tacaswell, I have tested this with Python 2.7 (Homebrew) and macosx backend, using the Side note: with |
@efiring OK I will have a look. |
fig : Figure | ||
A figure object which is assumed to be associated with a canvas | ||
""" | ||
if fig.stale and matplotlib.is_interactive(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Why limit this only to interactive backends?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
because if we are not interactive the user does not get updates? This is just mimicking the existing pyplot behavior ofdraw_if_interactive
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
"does not get updates" = "cannot update"? Well if we assume that, then we just add an unnecessary check....
However consider tools, if we add a tool that callsmy_line2d.set_color('purple')
, this line means you need to add acanvas.draw_idle()
after that in the tool, but if you run in interactive mode, you don't need it. This feels like inconsistent behaviour... but happy to get persuaded why we don't/may not want that.
This turned out to be a trivial problem. The MacOSX backend doesn't implement the draw_idle function, so matplotlib was calling draw_idle in the base class. However, the required functionality is available in the C extension, where it's called "invalidate" (this is what is currently used in draw_if_interactive). If I add a draw_idle method to FigureCanvasMac and let it call self.invalidate(), then everything seems to work fine. |
Perhaps related to@OceanWolf 's question: What is the purpose of using the callback functions _stale_figure_callback and _stale_axes_callback instead of setting figure.stale and axes.stale directly in stale.setter? |
@tacaswell, I had the same question as@mdehoon raised above; including a comment in the code to explain it might be helpful. |
It is a combination of the terrifying things that we do with the For 'normal' Artists it is the axes they are in, for The other part is looking forward to what I want to do with containers, being able to do the dispatch to parent via the call back stack allows artists to notify their container (which will in turn notify the axes) that they are stale. Being able to keep track of which parts of the tree are stale might provide a path to auto-blitting in the Agg backends (as we know exactly which artists we need to re-render and which we can used cached versions of), but that is still vapor ware. |
Did I break that or has that always been the case? |
@tacaswell, it's that way in master, and probably has always been that way, or at least has been in the modern era. It seems pretty fundamental. |
@tacaswell, I'm inclined to merge this now; is there any reason I should wait? |
I have been meaning to go back and re-work how the plain python shell It isn't hard, just some book keeping. If you want to merge this now I can On Thu, Jul 16, 2015 at 5:07 PM Eric Firingnotifications@github.com
|
Merged, so that we can get more people banging on it. |
jorgesca commentedJul 28, 2015
This morning I updated matpotlib master and then installedtrendvis I got an $pythonlines3d_demo.py/home/jscandal/sw/python/doct/ciarp07/lines3d_demo.pyTraceback (mostrecentcalllast):File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/backends/backend_qt5agg.py",line74,inpaintEventFigureCanvasAgg.draw(self)File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/backends/backend_agg.py",line471,indrawself.figure.draw(self.renderer)File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/artist.py",line60,indraw_wrapperdraw(artist,renderer,*args,**kwargs)File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/figure.py",line1121,indrawfunc(*args)File"/usr/lib/python3.4/site-packages/mpl_toolkits/mplot3d/axes3d.py",line273,indrawax.draw(renderer)File"/usr/lib/python3.4/site-packages/mpl_toolkits/mplot3d/axis3d.py",line264,indrawself.axes.transAxes.transform(peparray[0:2,0]))ValueError:Expected2-dimensionalarray,got1Traceback (mostrecentcalllast):File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/backends/backend_qt5agg.py",line74,inpaintEventFigureCanvasAgg.draw(self)File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/backends/backend_agg.py",line471,indrawself.figure.draw(self.renderer)File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/artist.py",line60,indraw_wrapperdraw(artist,renderer,*args,**kwargs)File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/figure.py",line1121,indrawfunc(*args)File"/usr/lib/python3.4/site-packages/mpl_toolkits/mplot3d/axes3d.py",line273,indrawax.draw(renderer)File"/usr/lib/python3.4/site-packages/mpl_toolkits/mplot3d/axis3d.py",line264,indrawself.axes.transAxes.transform(peparray[0:2,0]))ValueError:Expected2-dimensionalarray,got1 |
Did you follow the suggestion by@tacaswell ? (completely clean out previous installs of matplotlib/mpl_toolkits, then a |
@jorgesca Have you rebuilt the master branch? Working a bit on tests the past few days and I have run into problems needing to rebuild the c libraries...
|
jorgesca commentedJul 28, 2015
@WeatherGod and@OceanWolf Yes, I think I have followed the suggestion by@tacaswell , but will try once more in case a made a mistake. I'll report back soon |
You definitly have more than one version of mpl installed as File"/home/jscandal/sw/matplotlib/matplotlib.py3/lib/matplotlib/backends/backend_qt5agg.py",line74,inpaintEventFigureCanvasAgg.draw(self) vs File"/usr/lib/python3.4/site-packages/mpl_toolkits/mplot3d/axes3d.py",line273,indrawax.draw(renderer)File "/usr/lib/python3.4/site-packages/mpl_toolkits/``ThereissomeissuewhichIdonotfullyunderstandrelatedtohowthenamespacepackagesarehandledthatputsthemindifferentplaces.Istronglysuggestusingvirtualenvironmentstokeepthingsisolatedfromsystempython. |
jorgesca commentedJul 28, 2015
I must have done something wrong before, because the lines3d_demo works now. However, the examples from trendvis continue to raise the same error. Should I open a new issue with the details? I realize now my comments are on the wrong place, I apologize. |
Yes, please open a new issue with this. On Tue, Jul 28, 2015 at 2:33 PM Jorge Scandaliarisnotifications@github.com
|
This and#4503 should fix all of the problems discovered inb2fbae7
attn@efiring@mdehoon
Closes#4504