<br><br><div class="gmail_quote">On Sun, Jul 25, 2010 at 1:35 PM, Eric Firing <span dir="ltr">&lt;<a href="mailto:efiring@hawaii.edu">efiring@hawaii.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On 07/25/2010 09:10 AM, Brian Granger wrote:<br>
&gt; Gael,<br>
&gt;<br>
&gt; Great questions. †The short answer is that the traditional methods of<br>
&gt; discovering if the event loop is running won&#39;t work. †This issue will<br>
&gt; become even more complicated with we implement GUI integration in the<br>
&gt; new 2 process frontend/kernel. †We still need to decide how we are going<br>
&gt; to handle this. †Here was the last email we sent out a long time ago<br>
&gt; that didn&#39;t really get any response:<br>
<br>
</div>Brian,<br>
<br>
I&#39;ve been looking at that old message for a couple of weeks, trying to<br>
figure out how to respond from the mpl perspective. †I&#39;m still quite<br>
uncertain, and I would be pleased to see people with a better<br>
understanding of gui toolkits, event loops, and ipython step in.<br></blockquote><div><br></div><div>Part of the challenge is that Fernando and I (who have done the GUI work in IPython) don&#39;t know GUI toolkits very well.†</div>
<div><br></div><div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Preliminary thoughts:<br>
<br>
Although ipython has provided invaluable service to mpl by enabling<br>
interactive plotting for all gui backends, I am not at all sure that<br>
this functionality should be left to ipython in the long run. †The<br>
problem is that mpl is used in a variety of ways and environments. †Gui<br>
functionality is central to mpl; it seems odd, and unnecessarily<br>
complicated, to have to delegate part of that to an environment, or<br>
shell, like ipython.<br></blockquote><div><br></div><div>The challenge is that other projects (traits, mayavi, chaco, etc.) need these capabilities as well. †They either need to be in IPython or a separate project.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
At present, for most backends, interactive mpl plotting is possible in<br>
ipython without any of ipython&#39;s gui logic. †That is, running vanilla<br>
ipython one can:<br>
<br>
In [1]: from pylab import *<br>
<br>
In [2]: ion()<br>
<br>
In [3]: plot([1,2,3])<br>
Out[3]: [&lt;matplotlib.lines.Line2D object at 0x3f3c350&gt;]<br>
<br>
and the plot appears with full interaction, courtesy of the<br>
PyOS_InputHook mechanism used by default in tk, gtk, and qt4. †If mpl<br>
simply adopted the new ipython code to add this capability to wx, then<br>
wx* backends would be included. †The advantage over leaving this in<br>
ipython is that it would give mpl more uniform behavior regardless of<br>
whether it is run in ipython or elsewhere.<br></blockquote><div><br></div><div>Yes, tk, gtk and qt4 already use the input hook mechanism and it doesn&#39;t require IPython in any way. †At some level all the 0.11 IPython GUI support does is implement a PyOS_InputHook for wx and then provide a single interface for managing any GUI toolkit. †Maybe this code will eventually make its way into wx, but even then, it makes sense to have a single nice interface for this.</div>
<div>††</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Sometimes one wants mpl&#39;s show() to have blocking behavior. †At present<br>
it blocks when mpl is not in interactive mode. †The blocking is<br>
implemented by starting the gui event loop.<br>
<br>
One very useful service ipython provides is enabling mpl scripts with<br>
show() to be run in non-blocking mode. †I think this would be even<br>
better if one could easily choose whether to respect the interactive<br>
setting. †Then, one could either run a script in ipython exactly as it<br>
would be run from the command line--that is, blocking at each show() if<br>
not in interactive mode--or one could run it as at present in pylab<br>
mode. †I think this could be done with simple modifications of the pylab<br>
mode code.<br>
<br></blockquote><div><br></div><div>Yes.</div><div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I have no idea how all this will be affected by the proposed two-process<br>
model for ipython.<br>
<div class="im"><br></div></blockquote><div><br></div><div>The two process model will not use the inputhook stuff at all. †It will simple start a full GUI eventloop in the kernel process. †Because it is a very different approach than the inputhook approach we will need to think carefully about what interface we provide to projects like mpl.</div>
<div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
&gt;<br>
&gt; Current situation<br>
&gt; =============<br>
&gt;<br>
&gt; Both matplotlib and ets have code that tries to:<br>
&gt;<br>
&gt; * See what GUI toolkit is being used<br>
&gt; * Get the global App object if it already exists, if not create it.<br>
&gt; * See if the main loop is running, if not possibly start it.<br>
&gt;<br>
&gt; All of this logic makes many assumptions about how IPython affects the<br>
&gt; answers to these questions. †Because IPython&#39;s GUI support has changed<br>
&gt; in significant<br>
&gt; ways, current matplotlib and ets make incorrect decisions about these<br>
&gt; issues (such as trying to<br>
&gt; start the event loop a second time, creating a second main App ojbect,<br>
&gt; etc.) under IPython<br>
&gt; 0.11. †This leads to crashes...<br>
<br>
</div>This complexity is the reason why I would like to delegate all gui<br>
control back to mpl.<br>
<div class="im"><br></div></blockquote><div><br></div><div>We can&#39;t really do that. †The issue is that people want to use both mpl and traits and chaco in the same code. †If mpl is completely responsible for the GUI stuff, how will traits and chaco configure their GUI stuff. †The usual approach of seeing if there is a global app, and using it won&#39;t always work. †In the event loop is running using PyOS_InputHook, how will mpl/chaco/traits tell if the event loop is running?</div>
<div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
&gt;<br>
&gt; Description of GUI support in 0.11<br>
&gt; ==========================<br>
&gt;<br>
&gt; IPython allows GUI event loops to be run in an interactive IPython session.<br>
&gt; This is done using Python&#39;s PyOS_InputHook hook which Python calls<br>
&gt; when the :func:`raw_input` function is called and is waiting for user input.<br>
&gt; IPython has versions of this hook for wx, pyqt4 and pygtk. †When the<br>
&gt; inputhook<br>
&gt; is called, it iterates the GUI event loop until a user starts to type<br>
&gt; again. †When the user stops typing, the event loop iterates again. †This<br>
&gt; is how tk works.<br>
&gt;<br>
&gt; When a GUI program is used interactively within IPython, the event loop of<br>
&gt; the GUI should *not* be started. This is because, the PyOS_Inputhook itself<br>
&gt; is responsible for iterating the GUI event loop.<br>
&gt;<br>
&gt; IPython has facilities for installing the needed input hook for each GUI<br>
&gt; toolkit and for creating the needed main GUI application object. Usually,<br>
&gt; these main application objects should be created only once and for some<br>
&gt; GUI toolkits, special options have to be passed to the application object<br>
&gt; to enable it to function properly in IPython.<br>
<br>
</div>I don&#39;t know anything about these options. †I think that presently, mpl<br>
is always making the app object--but it is hard to keep all this<br>
straight in my head.<br>
<div class="im"><br></div></blockquote><div><br></div><div>Not quite. †When mpl is run in pylab mode in IPython, IPython always creates the App object. †It the monkey patches the App creation methods to return the existing version. †Thus, while it looks like mpl is creating the App objects, it isn&#39;t. †This type of monkey patching doesn&#39;t play well with the inputhook stuff.</div>
<div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
&gt;<br>
&gt; What we need to decide<br>
&gt; ===================<br>
&gt;<br>
&gt; We need to answer the following questions:<br>
&gt;<br>
&gt; * Who is responsible for creating the main GUI application object, IPython<br>
&gt; † or third parties (matplotlib, enthought.traits, etc.)?<br>
&gt;<br>
<br>
</div>At least for mpl, mpl always needs to be *able* to make it, since it<br>
can&#39;t depend on being run in ipython. †Therefore it seems simpler if mpl<br>
always *does* make it.<br>
<div class="im"><br></div></blockquote><div><br></div><div>This logic has to be conditional. †mpl will have to first look somewhere??? to see if someone else (IPython, traits, chaco) has created it and if the event loop is running. †This is the trick.</div>
<div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
&gt; * What is the proper way for third party code to detect if a GUI application<br>
&gt; † object has already been created? †If one has been created, how should<br>
&gt; † the existing instance be retrieved?<br>
&gt;<br>
<br>
</div>It would be simpler if third party code (mpl) did not *have* to do all<br>
this--if it could simply assume that it was responsible for creating and<br>
destroying the app object. †But maybe this is naive.<br>
<div class="im"><br></div></blockquote><div><br></div><div>Because multiple libraries all want to simultaneously to GUI stuff, there has to be a way for all of them to coordinate.</div><div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">
<br>
&gt; * In a GUI application object has been created, how should third party code<br>
&gt; † detect if the GUI event loop is running. It is not sufficient to call the<br>
&gt; † relevant function methods in the GUI toolkits (like ``IsMainLoopRunning``)<br>
&gt; † because those don&#39;t know if the GUI event loop is running through the<br>
&gt; † input hook.<br>
&gt;<br>
<br>
</div>Again, it seems so much simpler if the third party code can be left in<br>
control of all this, so the question does not even arise.<br>
<div class="im"><br>
&gt; * We might need a way for third party code to determine if it is running<br>
&gt; † in IPython or not. †Currently, the only way of running GUI code in IPython<br>
&gt; † is by using the input hook, but eventually, GUI based versions of IPython<br>
&gt; † will allow the GUI event loop in the more traditional manner. We will need<br>
&gt; † a way for third party code to distinguish between these two cases.<br>
&gt;<br>
<br>
</div>What are the non-hook methods you have in mind? †Maybe this option makes<br>
my proposed, or hoped-for, simplification impossible.<br>
<div class="im"><br></div></blockquote><div><br></div><div>The two process kernel/frontend will simply start the event loop in the kernel in the traditional way (non inputhook). †It has to do this because the entire kernel will be based on that event loop. †We have thought about if we could reuse the inputhook stuff there and it won&#39;t work.</div>
<div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
&gt; While we are focused on other things right now (the kernel/frontend) we<br>
&gt; would love to hear your thoughts on these issues. †Implementing a<br>
&gt; solution shouldn&#39;t be too difficult.<br>
<br>
</div>Another vague thought: †If we really need a more flexible environment,<br>
then maybe the way to achieve it is with a separate package or module<br>
that provides the API for collaboration between, e.g., ipython and mpl.<br>
 †Perhaps all the toolkit-specific event loop code could be factored out<br>
and wrapped in a toolkit-neutral API. †Then, an mpl interactive backend<br>
would use this API regardless of whether mpl is running in a script, or<br>
inside ipython. †In the latter case, ipython would be using the same<br>
API, providing centralized knowledge of, and control over, the app<br>
object and the loop. †I think that such a refactoring, largely combining<br>
existing functionality in ipython and mpl, might not be terribly<br>
difficult, and might make future improvements in functionality much<br>
easier. †It would also make it easier for other libraries to plug into<br>
ipython, collaborate with mpl, etc.<br>
<br></blockquote><div><br></div><div>This might make sense and as we move forward we should see if this makes sense. †My first thought though is that I don&#39;t want to track yet another project though.</div><div>†</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Even if the idea above is sound--and it may be completely<br>
impractical--the devil is undoubtedly in the details.<br>
<br></blockquote><div><br></div><div>And there are many ones in this case. †Thanks for participating in the discussion.</div><div><br></div><div>Brian</div><div><br></div><div>†</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Eric<br>
<div class="im"><br>
&gt;<br>
&gt; Cheers,<br>
&gt;<br>
&gt; Brian<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; On Sun, Jul 25, 2010 at 11:10 AM, Gael Varoquaux<br>
</div>&gt; &lt;<a href="mailto:gael.varoquaux@normalesup.org">gael.varoquaux@normalesup.org</a> &lt;mailto:<a href="mailto:gael.varoquaux@normalesup.org">gael.varoquaux@normalesup.org</a>&gt;&gt;<br>
<div class="im">&gt; wrote:<br>
&gt;<br>
&gt; † † With the 0.11 series of IPython, I no longer understand how the<br>
&gt; † † interaction with the GUI mainloop occurs:<br>
&gt;<br>
&gt; † † ----------------------------------------------------------------------<br>
&gt; † † $ ipython -wthread<br>
&gt;<br>
&gt; † † In [1]: import wx<br>
&gt;<br>
&gt; † † In [2]: wx.App.IsMainLoopRunning()<br>
&gt; † † Out[2]: False<br>
&gt; † † ----------------------------------------------------------------------<br>
&gt;<br>
&gt; † † ----------------------------------------------------------------------<br>
&gt; † † $ ipython -q4thread<br>
&gt; † † In [1]: from PyQt4 import QtGui<br>
&gt;<br>
&gt; † † In [2]: type(QtGui.QApplication.instance())<br>
&gt; † † Out[2]: &lt;type &#39;NoneType&#39;&gt;<br>
&gt; † † ----------------------------------------------------------------------<br>
&gt;<br>
&gt; † † Is there a mainloop running or not? If not, I really don&#39;t<br>
&gt; † † understand how<br>
&gt; † † I get interactivity with GUI windows and I&#39;d love an explaination or a<br>
&gt; † † pointer.<br>
&gt;<br>
&gt; † † The problem with this behavior is that there is a lot of code that<br>
&gt; † † checks<br>
&gt; † † if a mainloop is running, and if not starts one. This code thus blocks<br>
&gt; † † IPython and more or less defeats the purpose of the GUI options.<br>
&gt;<br>
&gt; † † Cheers,<br>
&gt;<br>
&gt; † † GaŽl<br>
&gt; † † _______________________________________________<br>
&gt; † † IPython-dev mailing list<br>
</div>&gt; † † <a href="mailto:IPython-dev@scipy.org">IPython-dev@scipy.org</a> &lt;mailto:<a href="mailto:IPython-dev@scipy.org">IPython-dev@scipy.org</a>&gt;<br>
<div class="im">&gt; † † <a href="http://mail.scipy.org/mailman/listinfo/ipython-dev" target="_blank">http://mail.scipy.org/mailman/listinfo/ipython-dev</a><br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; --<br>
&gt; Brian E. Granger, Ph.D.<br>
&gt; Assistant Professor of Physics<br>
&gt; Cal Poly State University, San Luis Obispo<br>
</div>&gt; <a href="mailto:bgranger@calpoly.edu">bgranger@calpoly.edu</a> &lt;mailto:<a href="mailto:bgranger@calpoly.edu">bgranger@calpoly.edu</a>&gt;<br>
&gt; <a href="mailto:ellisonbg@gmail.com">ellisonbg@gmail.com</a> &lt;mailto:<a href="mailto:ellisonbg@gmail.com">ellisonbg@gmail.com</a>&gt;<br>
<div><div></div><div class="h5">&gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; IPython-dev mailing list<br>
&gt; <a href="mailto:IPython-dev@scipy.org">IPython-dev@scipy.org</a><br>
&gt; <a href="http://mail.scipy.org/mailman/listinfo/ipython-dev" target="_blank">http://mail.scipy.org/mailman/listinfo/ipython-dev</a><br>
<br>
_______________________________________________<br>
IPython-dev mailing list<br>
<a href="mailto:IPython-dev@scipy.org">IPython-dev@scipy.org</a><br>
<a href="http://mail.scipy.org/mailman/listinfo/ipython-dev" target="_blank">http://mail.scipy.org/mailman/listinfo/ipython-dev</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>Brian E. Granger, Ph.D.<br>Assistant Professor of Physics<br>Cal Poly State University, San Luis Obispo<br><a href="mailto:bgranger@calpoly.edu">bgranger@calpoly.edu</a><br>
<a href="mailto:ellisonbg@gmail.com">ellisonbg@gmail.com</a><br>