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

Expose a magic to control config of the inline pylab backend #903

Closed
fperez opened this issue Oct 19, 2011 · 8 comments · Fixed by #923
Closed

Expose a magic to control config of the inline pylab backend #903

fperez opened this issue Oct 19, 2011 · 8 comments · Fixed by #923

Comments

@fperez
Copy link
Member

fperez commented Oct 19, 2011

We should provide a magic to provide easy, user-level control of certain features of the inline backend. Something like

%inline_backend close_figures=True
%inline_backend figure_format = 'svg'

would allow easy runtime control of the points discussed in #638 and #781.

In the long run, ideally we'd fold this into a richer %pylab magic that allows initializing pylab mode in the qtconsole/notebooks (like it does in the terminal), toggling of floating/inline figures and inline configuration. But since that's a larger job, as discussed at the end of #892, it's probably best left for a separate task.

Marking this as high priority for 0.12 in case we manage to pull it off, as it would be great to have out of the gate when we release the notebook. But I'm not willing to make it a blocker as we're getting close to the wire, so it may slip to 0.13.

@ellisonbg
Copy link
Member

Instead of proliferating lots of special purpose magics to configure specific items, we should make a single magic that can easily configure anything in ipython. Something like %config Foo.bar=10

@fperez
Copy link
Member Author

fperez commented Oct 19, 2011

Yes, we'd discussed that in #892 already. I'm certainly happy to go there, but as indicated in the discussion, it is unfortunately more complicated for the general case. In the case of pylab, those objects actually check their config flags at runtime, so modifying the config object itself is sufficient to impact behavior in the expected way. But not all configurables are like this, in some cases the objects use config data at initialization time only, so a %config that modifies arbitrary configurables may effectively be a no-op for some objects.

Because of the higher complexity of the general problem, and the value of run-time control of the plotting behavior, is why we've been talking about having a specific magic for this.

But I am very much sympathetic to the worry about magics sprouting like dandelions. As indicated atop, this behavior could just go into %pylab (which fortunately already exists), and we can simply refine %pylab over time until we get run-time activation for nb/qt and runtime switching of inline/floating.

That would be my preferred solution for now, even if we don't get the two last things done right away.

@minrk
Copy link
Member

minrk commented Oct 24, 2011

I think I've figured out how to to a generic %config magic without significant difficulty. Should I go that route, or also make the inline backend config accessible from %pylab?

I actually have both working locally right now, so you can do:

%pylab InlineBackendConfig.figure_format = 'png'

or

%pylab inline.figure_format='png'

I'll do a PR soon, starting with just %config. The advantage of %pylab-style is it's more user-friendly, whereas %config is more developer-friendly. In order for %config to be useful, you already have to know a lot about IPython's class structure, whereas we can shortcut that if we want to expose a shortlist of high-visibility options.

@minrk minrk mentioned this issue Oct 24, 2011
@fperez
Copy link
Member Author

fperez commented Oct 24, 2011

On Mon, Oct 24, 2011 at 12:50 AM, Min RK
reply@reply.github.com
wrote:

I'll do a PR soon, starting with just %config.  The advantage of %pylab-style is it's more user-friendly, whereas %config is more developer-friendly.  In order for %config to be useful, you already have to know a lot about IPython's class structure, whereas we can shortcut that if we want to expose a shortlist of high-visibility options.

This makes a good case for both. Most regular users (think students
in a classroom who just want to plot their data) will find the
low-level api daunting, even though it will be valuable to developers.
It's kind of like the gnome control center vs gconf-editor: they both
serve a purpose, even though there's a bit of overlap/duplication in a
few places.

@minrk
Copy link
Member

minrk commented Oct 24, 2011

Okay. I've started the PR (#923) with the %config stuff. What should the %pylab one look like? My first draft is that it's really identical to using %config, but replacing 'InlineBackendConfig' with 'inline':

%pylab inline.figure_format = 'png'

Which I'm not certain has a sufficient benefit over simply directing the user to %config InlineBackendConfig in the %pylab helpstring.

(by the way, can I express regret in calling it InlineBackendConfig instead of InlineBackend? code like config.update(InlineBackendConfig.config) is not awesome)

I also tried a version using the KVLoader, so that you could set multiple parameters at once (the %config magic only allows one at a time, because I think the KV line parsing is too strict for more general use, e.g. no spaces around '=').

There are also various other, more hardcoded forms I can do, like:

%pylab inline png
%pylab inline svg
%pylab inline closefigs
%pylab inline keepfigs

Which are more concise, and perhaps easier to remember for those people who only want to flip that one switch they actually use.

A general disadvantage of the %config magic from a usability standpoint is that there is no indication of which traits would actually have an effect on change (most simple flags, etc.), and which traits only have an effect at startup (colors, readline, various proxy traits).

An advantage of the %config magic is discoverability:

# what can I configure in IPython?
In [7]: %config
Available objects for config:
     TerminalInteractiveShell
     HistoryManager
     PrefilterManager
     AliasManager
     IPCompleter
     DisplayFormatter

# okay, what can I configure in the DisplayFormatter?
In [8]: %config DisplayFormatter
DisplayFormatter options
----------------------
DisplayFormatter.plain_text_only=<Bool>
    Current: True
DisplayFormatter.formatters=<Dict> ... # this should *not* be a configurable, it's a dict of instances

# now I can configure these values
In [9]: %config DisplayFormatter.plain_text_only = False

@ellisonbg
Copy link
Member

Not many people know about the InlineBackendConfig as of yet, so I think that renaming it to InlineBackend at this point would be fine.

@ellisonbg
Copy link
Member

I don't view our config system as an advanced API that most users should not touch. I view it as the way of configuring IPython. We should vigorously encourage its usage for all users.

The main disadvantage I see with the custom %pylab magic is that users who use that will have to learn a completely different syntax to affect those changes in their config files. That is more confusing that simply having them use a well designed %config magic in the first place.

@minrk
Copy link
Member

minrk commented Oct 24, 2011

It's not that users shouldn't touch it, it's just a matter of sensory overload when confronted with 100% of the configurable namespace. We are always going to have to maintain a shortlist of common actions at higher visibility, especially when a huge fraction of the configurables (particularly on InteractiveShell) have no effect after launch.

I will, though, just add a reference to %config InlineBackend to the %pylab docstring, rather than adding any custom handling there.

I'll go ahead and change InlineBackendConfig to InlineBackend. Do we have an official approach for deprecations like this?

@fperez fperez closed this as completed in b725362 Oct 29, 2011
mattvonrocketstein pushed a commit to mattvonrocketstein/ipython that referenced this issue Nov 3, 2014
New %config magic to interactively manipulate all configurables.

This allows users to type `%config Foo.bar = 5` to control any IPython configurable.

The Magic class keeps a list of configurables which will be updated by the change, so any objects that should be accessible to this magic should be appended to `shell.configurables`.  I started with everything I saw as configurable in InteractiveShell.

## Usage

Use just `%config` to see what classes are available, and `%config Class` to get the trait info for that class.

When setting values via` %config Class.trait = value` It is evaluated with user_ns in globals, so you can do arbitrary things like:

```python
In [4]: default = 'png'

In [5]: %config InlineBackendConfig.figure_format = raw_input('what figure format should we use? ') or default
```

## Note

This magic reveals just how much we *don't* use traits/config properly.  Almost everything is attached to the InteractiveShell object, and has an effect exactly once during an `init_foo()` method, rather than allowing config propagation via `_trait_changed()` methods.

For instance, IPCompleter has an `omit__names` attribute, but the configurable is `InteractiveShell.readline_omit__names`, which is clearly wrong.

We've done a good job with config in *new* code, but I think existing code needs a pretty hefty pass to get configurables attached to the right objects, and getting logic like `%colors` into `shell._colors_changed`.

Closes ipython#903
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants