Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pylab import adjustments #3568

Merged
merged 13 commits into from Jul 17, 2013
Merged

pylab import adjustments #3568

merged 13 commits into from Jul 17, 2013

Conversation

minrk
Copy link
Member

@minrk minrk commented Jul 6, 2013

  • add %pylab --no-import
    • allows override of the import_all option when the magic is called
  • adjust import_pylab to import nothing when import_all is False

it's all or nothing now, not all or some. Now pylab_import_all=False should mean that no symbols are added to the user namespace.

This also removes figsize from the pyplot namespace, which was weird and confusing.

closes #2630
closes #2664
closes #3436

@asmeurer
Copy link
Contributor

asmeurer commented Jul 6, 2013

I didn't test the magic, but this seems to fix the use from isympy.

Thanks for adding the flag to the magic. That will be useful for SymPy's example notebooks.

@asmeurer
Copy link
Contributor

asmeurer commented Jul 6, 2013

What was the final decision about warning users about imports from #2664?

@minrk
Copy link
Member Author

minrk commented Jul 6, 2013

I've added a warning. I'm ambivalent about its desirability.

@Carreau
Copy link
Member

Carreau commented Jul 9, 2013

Looks fine to me and warning is not too intrusive.

@ivanov
Copy link
Member

ivanov commented Jul 9, 2013

this changes the meaning of c.InteractiveShellApp.pylab_import_all flag, so we need to at least reflect that on lines 179-180 of IPython/core/shellapp.py.

With this change, it will no longer be possible to have the old behavior of having plt and np imported, but not things like sin and cos for someone who has c.InteractiveShellApp.pylab_import_all = False. Might it make more sense to retain the old meaning of pylab_import_all flag, and add an additional configurable like pylab_import_none

additionally, if this change goes in, we should note it down in docs/source/whatsnew/development.txt

@asmeurer
Copy link
Contributor

asmeurer commented Jul 9, 2013

IMHO you shouldn't do that. As far as I'm concerned, the importing of np and so on with import_all=False was a bug. The name "import all" may suggest different things to different people, but I'm pretty sure that most people who were using import_all=False were doing so to prevent adding junk to the namespace. import_none just seems like unnecessary complexity. If you really want np, etc. you can always import them yourself the old fashioned way.

But +1 regardless for documenting these changes in release notes or somewhere similar.

@ivanov
Copy link
Member

ivanov commented Jul 9, 2013

the meaning of pylab_import_all was pretty explicit before: If true, an 'import *' is done from numpy and pylab, when using pylab

@takluyver
Copy link
Member

It wasn't a bug - the code and the docs were pretty clear that it was
intended to work that way. It's not clear how many people use the setting,
and how many rely on getting np and plt. Having a separate flag sounds like
unnecessary complexity to me, but maybe it's worth pinging the lists to see
if people were using it like that.

On 9 July 2013 21:26, Paul Ivanov notifications@github.com wrote:

the meaning of pylab_import_all was pretty explicit before: If true, an
'import *' is done from numpy and pylab, when using pylab


Reply to this email directly or view it on GitHubhttps://github.com//pull/3568#issuecomment-20702796
.

@asmeurer
Copy link
Contributor

asmeurer commented Jul 9, 2013

Aside from the known use of SymPy, you can check with @jenshnielsen who originally implemented it at #551. SymPy's use doesn't want anything imported (we just want to setup the eventloop). Since the eventloop setup is so important, and really unrelated to imports, I can imagine that that would be a very common use-case.

@minrk
Copy link
Member Author

minrk commented Jul 9, 2013

It may not have been a bug, but I think it was the wrong decision. I don't think there are many (or any) people who want all the imports except *, but I think there are those who want to say "let me do my own imports". I think all or nothing is much more logical choice than all or some.

Help string has been updated.

@ivanov
Copy link
Member

ivanov commented Jul 9, 2013

without the * imports, all you got in pylab mode was plt and np, along with matplotlib and pylab - it was just a way of preserving the whole "namespaces is a good idea" but not having to do those imports. That was the way I remember @fperez talking about it when teaching this stuff at the early berkeley bootcamps

@asmeurer
Copy link
Contributor

asmeurer commented Jul 9, 2013

But look at it from the point of view of someone like me who just wants to setup the eventloop without importing stuff (preferably without even importing it internally unless it has to, for speed purposes). With a second option, it gets complicated. %pylab --import-all=False is already complicated enough. I completely agree with Min on this.

@minrk
Copy link
Member Author

minrk commented Jul 9, 2013

I think there's a fairly simple issue here - there are users who didn't like that we touched their namespace. As a direct result, we added the pylab_import_all flag. But this doesn't do what was actually requested, which was to just leave the namespace alone.

@ivanov
Copy link
Member

ivanov commented Jul 10, 2013

So I had a chance to sleep on this (still sick, so hooray for naps!) and it seems fishy to have a flag to %pylab that makes %pylab not do anything %pylab specific. I could be wrong, but doesn't %pylab --no-import become functionally equivalent to %gui? So from the perspective of the use case @asmeurer specified, %gui should be used, and not %pylab

@asmeurer
Copy link
Contributor

I didn't know about %gui. Is it functionally equivalent to pylab? Really, at the end of the day, I just want inline plots in the notebook and qtconsole and nonblocking plots in the terminal.

@ellisonbg
Copy link
Member

%gui doesn't setup the matplotlib backends. This usage case really does
need %pyline inline --no-import.

On Tue, Jul 9, 2013 at 7:58 PM, Aaron Meurer notifications@github.comwrote:

I didn't know about %gui. Is it functionally equivalent to pylab? Really,
at the end of the day, I just want inline plots in the notebook and
qtconsole and nonblocking plots in the terminal.


Reply to this email directly or view it on GitHubhttps://github.com//pull/3568#issuecomment-20718968
.

Brian E. Granger
Cal Poly State University, San Luis Obispo
bgranger@calpoly.edu and ellisonbg@gmail.com

@ivanov
Copy link
Member

ivanov commented Jul 10, 2013

I just checked, and the behavior and meaning of pylab_import_all hasn't changed since 0.8.4 (actually before that, the changelog notes this change on 2007-03-18)

# Pylab support: when ipython is started with the -pylab switch, by default it
# executes 'from matplotlib.pylab import *'.  Set this variable to false if you
# want to disable this behavior.

# For details on pylab, see the matplotlib website:
# http://matplotlib.sf.net
pylab_import_all 1

The additional (unconditional) namespace imports (numpy as np, etc)were put in after (circa rel-0.9): (line IPython/Shell.py:571-582)

        # Import numpy as np/pyplot as plt are conventions we're trying to
        # somewhat standardize on.  Making them available to users by default
        # will greatly help this. 
        exec ("import numpy\n"
              "import numpy as np\n"
              "import matplotlib\n"
              "import matplotlib.pylab as pylab\n"
              "try:\n"
              "    import matplotlib.pyplot as plt\n"
              "except ImportError:\n"
              "    pass\n"
              ) in user_ns

@jenshnielsen
Copy link
Contributor

@ivanov is right. I reimplemented the pylab_import_all functionality for IPython post 0.11 matching the original implementation. The functionality was lost in the transition to the new config system, all I did was to restore it to match the orignal behaviour.

I am split on this behaviour, on one hand it will break existing notebooks and I find it quite logical that a matplotlib
event loop integration imports pyplot. I also like the common use of numpy as np and pyplot as plt which this somewhat enforces. On the other hand explicite imports are usually better than implicit ones.

@ellisonbg
Copy link
Member

Would it clarify the code some of we renamed the boolean variable pylab_imports?

@asmeurer
Copy link
Contributor

I also like the common use of numpy as np and pyplot as plt which this somewhat enforces.

You are still thinking of pylab as something that imports stuff, but I want behavior that doesn't import stuff, just sets up the eventloop.

Can someone clarify something about the eventloop integration. Do numpy and/or matplotlib have to be imported for that to be set up?

@minrk
Copy link
Member Author

minrk commented Jul 10, 2013

It does all kinds of pylab stuff - setting up the inline backend, selecting the matplotlib backend, activating figure formatters. Imports are only one piece of what pylab does, and it really should be optional.

I didn't realize the import_all switch had existed prior to the addition of the config value, thanks. I had never heard of anyone using it before the config value, but plenty of complaints about not being able to set up matplotlib without affecting the namespace.

@asmeurer
Copy link
Contributor

OK, so there's no hope of making it faster by not importing things.

@minrk
Copy link
Member Author

minrk commented Jul 10, 2013

No, if speed is your concern, this has no effect at all - everything being added to is already imported, just not in the interactive namespace.

@minrk
Copy link
Member Author

minrk commented Jul 12, 2013

Just chatted with @fperez, and here's an alternate proposal:

  • leave %pylab unchanged (aside from cleaning up the imports that only happened for some backends)
  • add %matplotlib magic, which does no imports
  • %pylab is simplified, it just implies %matplotlib then import_pylab.

I'm pretty sure a proposal very similar to this has been made before, but nobody has actually implemented it.

Thoughts, @asmeurer @ivanov?

@asmeurer
Copy link
Contributor

What about the internal API? I like this idea, though it does make --import-all a little redundant.

@asmeurer
Copy link
Contributor

Sorry, when I say "internal API", I mean "Python API". I care about how SymPy will call out to this from its init_printing.

@minrk
Copy link
Member Author

minrk commented Jul 13, 2013

You would call shell.enable_matplotlib() - the eventloop and display formatters would be hooked up, no imports performed.

@minrk
Copy link
Member Author

minrk commented Jul 13, 2013

and no messages displayed

@asmeurer
Copy link
Contributor

+1.

It's probably too late to integrate this API into SymPy 0.7.3 (I plan to do the final release either tomorrow or Sunday; yay we finally get a release out before you guys), but it's not big deal, because I think we are finally approaching a point with SymPy where we can release on a regular basis.

magic_gui_arg = magic_arguments.argument(
'gui', nargs='?',
help="""Name of the matplotlib backend to use
('qt', 'wx', 'gtk', 'osx', 'tk', 'inline', 'auto').
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not worth holding up this PR, but I tend to prefer interpolating strings like this from some programmatically available list (so if we change the list of backends, we don't have to update such string in a whole bunch of different places), Something like from IPython.core.pylabtools import backends and then interpolate in sorted(backends.keys())

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, sent you a PR that includes a change for this

@ivanov
Copy link
Member

ivanov commented Jul 17, 2013

I sent you a PR that fixes two failing tests, but there's still one more failing for the inprocesss kernel:

$ python /home/pi/code/ipython/IPython/testing/iptest.py IPython.kernel.inprocess
E.......
======================================================================
ERROR: Does pylab work in the in-process kernel?
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pi/code/ipython/IPython/testing/decorators.py", line 232, in skipper_func
    return f(*args, **kwargs)
  File "/home/pi/code/ipython/IPython/kernel/inprocess/tests/test_kernel.py", line 44, in test_pylab
    msg = get_stream_message(kc)
  File "/home/pi/code/ipython/IPython/kernel/inprocess/tests/test_kernel.py", line 85, in get_stream_message
    msg = kernel_client.get_iopub_msg(timeout=timeout)
  File "/home/pi/code/ipython/IPython/kernel/client.py", line 89, in get_iopub_msg
    return self.iopub_channel.get_msg(*args, **kwargs)
  File "/home/pi/code/ipython/IPython/kernel/blocking/channels.py", line 41, in get_msg
    return self._in_queue.get(block, timeout)
  File "/usr/lib/python2.7/Queue.py", line 176, in get
    raise Empty
Empty: 
-------------------- >> begin captured logging << --------------------
IPython.kernel.inprocess.ipkernel: DEBUG: 
*** MESSAGE TYPE:execute_request***
IPython.kernel.inprocess.ipkernel: DEBUG:    Content: {'user_variables': [], 'code': '%pylab', 'silent': False, 'allow_stdin': True, 'store_history': True, 'user_expressions': {}}
   --->

IPython.kernel.inprocess.ipkernel: INFO: Exception in execute request:
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-5c1faa999e5b> in <module>()
----> 1 get_ipython().magic(u'pylab')

/home/pi/code/ipython/IPython/core/interactiveshell.pyc in magic(self, arg_s)
   2152         magic_name, _, magic_arg_s = arg_s.partition(' ')
   2153         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-> 2154         return self.run_line_magic(magic_name, magic_arg_s)
   2155 
   2156     #-------------------------------------------------------------------------

/home/pi/code/ipython/IPython/core/interactiveshell.pyc in run_line_magic(self, magic_name, line)
   2073                 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
   2074             with self.builtin_trap:
-> 2075                 result = fn(*args,**kwargs)
   2076             return result
   2077 

/home/pi/code/ipython/IPython/core/magics/pylab.pyc in pylab(self, line)

/home/pi/code/ipython/IPython/core/magic.pyc in <lambda>(f, *a, **k)
    189     # but it's overkill for just that one bit of state.
    190     def magic_deco(arg):
--> 191         call = lambda f, *a, **k: f(*a, **k)
    192 
    193         if callable(arg):

/home/pi/code/ipython/IPython/core/magics/pylab.pyc in pylab(self, line)
    128             import_all = not args.no_import_all
    129 
--> 130         gui, backend, clobbered = self.shell.enable_pylab(args.gui, import_all=import_all)
    131         self._show_matplotlib_backend(args.gui, backend)
    132         if clobbered:

TypeError: 'NoneType' object is not iterable
IPython.kernel.inprocess.ipkernel: DEBUG: {'parent_header': {'date': datetime.datetime(2013, 7, 16, 17, 53, 18, 286584), 'username': 'pi', 'session': '4c79ecdf-d53e-4d0a-a1ce-d8190d71fe7f', 'msg_id': '6e4b19ab-ed6e-40df-bbdf-a1a61dfb2c54', 'msg_type': 'execute_request'}, 'msg_type': u'execute_reply', 'msg_id': '174ecae8-f78d-4d93-8195-157e4edc313b', 'content': {'status': u'error', 'ename': u'TypeError', 'user_variables': {}, 'evalue': u"'NoneType' object is not iterable", 'traceback': [u'\x1b[1;31m---------------------------------------------------------------------------\x1b[0m\n\x1b[1;31mTypeError\x1b[0m                                 Traceback (most recent call last)', u"\x1b[1;32m<ipython-input-1-5c1faa999e5b>\x1b[0m in \x1b[0;36m<module>\x1b[1;34m()\x1b[0m\n\x1b[1;32m----> 1\x1b[1;33m \x1b[0mget_ipython\x1b[0m\x1b[1;33m(\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mmagic\x1b[0m\x1b[1;33m(\x1b[0m\x1b[1;34mu'pylab'\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0m", u"\x1b[1;32m/home/pi/code/ipython/IPython/core/interactiveshell.pyc\x1b[0m in \x1b[0;36mmagic\x1b[1;34m(self, arg_s)\x1b[0m\n\x1b[0;32m   2152\x1b[0m         \x1b[0mmagic_name\x1b[0m\x1b[1;33m,\x1b[0m \x1b[0m_\x1b[0m\x1b[1;33m,\x1b[0m \x1b[0mmagic_arg_s\x1b[0m \x1b[1;33m=\x1b[0m \x1b[0marg_s\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mpartition\x1b[0m\x1b[1;33m(\x1b[0m\x1b[1;34m' '\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m   2153\x1b[0m         \x1b[0mmagic_name\x1b[0m \x1b[1;33m=\x1b[0m \x1b[0mmagic_name\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mlstrip\x1b[0m\x1b[1;33m(\x1b[0m\x1b[0mprefilter\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mESC_MAGIC\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[1;32m-> 2154\x1b[1;33m         \x1b[1;32mreturn\x1b[0m \x1b[0mself\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mrun_line_magic\x1b[0m\x1b[1;33m(\x1b[0m\x1b[0mmagic_name\x1b[0m\x1b[1;33m,\x1b[0m \x1b[0mmagic_arg_s\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0m\x1b[0;32m   2155\x1b[0m \x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m   2156\x1b[0m     \x1b[1;31m#-------------------------------------------------------------------------\x1b[0m\x1b[1;33m\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n", u"\x1b[1;32m/home/pi/code/ipython/IPython/core/interactiveshell.pyc\x1b[0m in \x1b[0;36mrun_line_magic\x1b[1;34m(self, magic_name, line)\x1b[0m\n\x1b[0;32m   2073\x1b[0m                 \x1b[0mkwargs\x1b[0m\x1b[1;33m[\x1b[0m\x1b[1;34m'local_ns'\x1b[0m\x1b[1;33m]\x1b[0m \x1b[1;33m=\x1b[0m \x1b[0msys\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0m_getframe\x1b[0m\x1b[1;33m(\x1b[0m\x1b[0mstack_depth\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mf_locals\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m   2074\x1b[0m             \x1b[1;32mwith\x1b[0m \x1b[0mself\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mbuiltin_trap\x1b[0m\x1b[1;33m:\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[1;32m-> 2075\x1b[1;33m                 \x1b[0mresult\x1b[0m \x1b[1;33m=\x1b[0m \x1b[0mfn\x1b[0m\x1b[1;33m(\x1b[0m\x1b[1;33m*\x1b[0m\x1b[0margs\x1b[0m\x1b[1;33m,\x1b[0m\x1b[1;33m**\x1b[0m\x1b[0mkwargs\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0m\x1b[0;32m   2076\x1b[0m             \x1b[1;32mreturn\x1b[0m \x1b[0mresult\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m   2077\x1b[0m \x1b[1;33m\x1b[0m\x1b[0m\n", u'\x1b[1;32m/home/pi/code/ipython/IPython/core/magics/pylab.pyc\x1b[0m in \x1b[0;36mpylab\x1b[1;34m(self, line)\x1b[0m\n', u"\x1b[1;32m/home/pi/code/ipython/IPython/core/magic.pyc\x1b[0m in \x1b[0;36m<lambda>\x1b[1;34m(f, *a, **k)\x1b[0m\n\x1b[0;32m    189\x1b[0m     \x1b[1;31m# but it's overkill for just that one bit of state.\x1b[0m\x1b[1;33m\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m    190\x1b[0m     \x1b[1;32mdef\x1b[0m \x1b[0mmagic_deco\x1b[0m\x1b[1;33m(\x1b[0m\x1b[0marg\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m:\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[1;32m--> 191\x1b[1;33m         \x1b[0mcall\x1b[0m \x1b[1;33m=\x1b[0m \x1b[1;32mlambda\x1b[0m \x1b[0mf\x1b[0m\x1b[1;33m,\x1b[0m \x1b[1;33m*\x1b[0m\x1b[0ma\x1b[0m\x1b[1;33m,\x1b[0m \x1b[1;33m**\x1b[0m\x1b[0mk\x1b[0m\x1b[1;33m:\x1b[0m \x1b[0mf\x1b[0m\x1b[1;33m(\x1b[0m\x1b[1;33m*\x1b[0m\x1b[0ma\x1b[0m\x1b[1;33m,\x1b[0m \x1b[1;33m**\x1b[0m\x1b[0mk\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0m\x1b[0;32m    192\x1b[0m \x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m    193\x1b[0m         \x1b[1;32mif\x1b[0m \x1b[0mcallable\x1b[0m\x1b[1;33m(\x1b[0m\x1b[0marg\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m:\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n", u'\x1b[1;32m/home/pi/code/ipython/IPython/core/magics/pylab.pyc\x1b[0m in \x1b[0;36mpylab\x1b[1;34m(self, line)\x1b[0m\n\x1b[0;32m    128\x1b[0m             \x1b[0mimport_all\x1b[0m \x1b[1;33m=\x1b[0m \x1b[1;32mnot\x1b[0m \x1b[0margs\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mno_import_all\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m    129\x1b[0m \x1b[1;33m\x1b[0m\x1b[0m\n\x1b[1;32m--> 130\x1b[1;33m         \x1b[0mgui\x1b[0m\x1b[1;33m,\x1b[0m \x1b[0mbackend\x1b[0m\x1b[1;33m,\x1b[0m \x1b[0mclobbered\x1b[0m \x1b[1;33m=\x1b[0m \x1b[0mself\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mshell\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0menable_pylab\x1b[0m\x1b[1;33m(\x1b[0m\x1b[0margs\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mgui\x1b[0m\x1b[1;33m,\x1b[0m \x1b[0mimport_all\x1b[0m\x1b[1;33m=\x1b[0m\x1b[0mimport_all\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0m\x1b[0;32m    131\x1b[0m         \x1b[0mself\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0m_show_matplotlib_backend\x1b[0m\x1b[1;33m(\x1b[0m\x1b[0margs\x1b[0m\x1b[1;33m.\x1b[0m\x1b[0mgui\x1b[0m\x1b[1;33m,\x1b[0m \x1b[0mbackend\x1b[0m\x1b[1;33m)\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n\x1b[0;32m    132\x1b[0m         \x1b[1;32mif\x1b[0m \x1b[0mclobbered\x1b[0m\x1b[1;33m:\x1b[0m\x1b[1;33m\x1b[0m\x1b[0m\n', u"\x1b[1;31mTypeError\x1b[0m: 'NoneType' object is not iterable"], 'execution_count': 1, 'user_expressions': {}, 'engine_info': {'engine_uuid': u'73491990-3afb-4854-84c4-7d6d20ad3059', 'method': u'execute', 'engine_id': -1}, 'payload': []}, 'header': {'date': datetime.datetime(2013, 7, 16, 17, 53, 18, 431425), 'username': u'pi', 'session': u'658bbcfc-fde1-473a-ba76-150325356ece', 'msg_id': '174ecae8-f78d-4d93-8195-157e4edc313b', 'msg_type': u'execute_reply'}, 'tracker': <zmq.sugar.tracker.MessageTracker object at 0x4f8ac50>, 'metadata': {'dependencies_met': True, 'engine': u'73491990-3afb-4854-84c4-7d6d20ad3059', 'status': u'error', 'started': datetime.datetime(2013, 7, 16, 17, 53, 18, 287394)}}
--------------------- >> end captured logging << ---------------------

----------------------------------------------------------------------
Ran 8 tests in 5.410s

FAILED (errors=1)

@minrk
Copy link
Member Author

minrk commented Jul 17, 2013

@ivanov thanks, merged your PR, and the inprocess failure should be fixed as well.

@ivanov
Copy link
Member

ivanov commented Jul 17, 2013

alright, status ok, thanks Min, merging!

ivanov added a commit that referenced this pull request Jul 17, 2013
new %matplotlib magic, quieter %pylab magic

%matplotlib is a magic which sets up integration but does no imports
%pylab now is now as verbose about announcing itself.
@ivanov ivanov merged commit 9e253ec into ipython:master Jul 17, 2013
@Carreau
Copy link
Member

Carreau commented Jul 17, 2013

So now, we should tell peolple to use %matplotlib preferably in many places where we used %pylab right?

@ivanov
Copy link
Member

ivanov commented Jul 17, 2013

that's right, Matthias, @minrk and I were also talking about eventually adding an %import magic that would allow other packages to effectively set up some form of integration with ipython, but with a minimal amount of work, and in a manner that'd be natural for the user to also expect an imported package to be there afterwards. so %import matplotlib will finally be the preferred method once we put such machinery in place (goes without saying that this is not 1.0 material)

@asmeurer
Copy link
Contributor

What is the API call?

@minrk
Copy link
Member Author

minrk commented Jul 17, 2013

@asmeurer the idea (which came from @fperez) is to generalize %load_ext a little bit, which currently uses load_ipython_extension(ip). It might mean adding ipython_import_hook(ip), or just extending the interpretation of the existing load_ipython_extension without a new function to call. Right now, this mostly lives in @fperez's head.

@minrk minrk deleted the pylab-no-import branch July 17, 2013 22:19
@asmeurer
Copy link
Contributor

Actually, I mean what is the API call associated with %matplotlib. But I see now from the commit messages that it's just enable_matplotlib.

@minrk
Copy link
Member Author

minrk commented Jul 17, 2013

Right, sorry - yes, the various %gui, %matplotlib, %pylab magics all just map onto enable_<magicname>.

@asmeurer
Copy link
Contributor

Wait, so what is %gui then?

@minrk
Copy link
Member Author

minrk commented Jul 17, 2013

%gui just hooks up IPython with a GUI eventloop (qt, wx, gtk, etc.). %matplotlib also selects a matplotlib backend and hooks up display formatters.

@asmeurer
Copy link
Contributor

Ah, so there is a strict hierarchy of magics %gui -> %matplotlib -> %pylab that call the previous ones.

@minrk
Copy link
Member Author

minrk commented Jul 18, 2013

yes - though technically only one magic is ever actually called, but multiple enable_foo calls may be made.

@asmeurer
Copy link
Contributor

I just wanted to be sure that my hierarchy is right here.

+----------------+
|     pylab      |
|                |
| +------------+ |
| | matplotlib | |
| |            | |
| |  +-----+   | |
| |  | gui |   | |
| |  +-----+   | |
| +------------+ |
+----------------+

@minrk
Copy link
Member Author

minrk commented Jul 18, 2013

exactly right, yes.

ivanov added a commit to ivanov/ipython that referenced this pull request Jul 21, 2013
Now that ipython#3568 is merged, we should steer folks in that direction
mattvonrocketstein pushed a commit to mattvonrocketstein/ipython that referenced this pull request Nov 3, 2014
new %matplotlib magic, quieter %pylab magic

%matplotlib is a magic which sets up integration but does no imports
%pylab now is now as verbose about announcing itself.
mattvonrocketstein pushed a commit to mattvonrocketstein/ipython that referenced this pull request Nov 3, 2014
Now that ipython#3568 is merged, we should steer folks in that direction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants