olgabot / prettyplotlib

Painlessly create beautiful matplotlib plots.
olgabot.github.io/prettyplotlib
MIT License
1.69k stars 148 forks source link

Colors are not set correctly #52

Closed domoritz closed 10 years ago

domoritz commented 10 years ago

It looks like with matplotlib 1.3.1 plotting doesn't pick up the right colors.

numpy==1.7.1 prettyplotlib==0.1.7 brewer2mpl==1.4 matplotlib==1.3.1

I'm looking at the example from https://github.com/olgabot/prettyplotlib/wiki/Examples-with-code#plot-lines-eg-time-series-with-a-legend

import prettyplotlib as ppl
import numpy as np

# prettyplotlib imports 
import matplotlib.pyplot as plt
import matplotlib as mpl
from prettyplotlib import brewer2mpl

# Set the random seed for consistency
np.random.seed(12)

fig, ax = plt.subplots(1)

# Show the whole color range
for i in range(8):
    y = np.random.normal(size=1000).cumsum()
    x = np.arange(1000)

    # For now, you need to specify both x and y :(
    # Still figuring out how to specify just one
    ppl.plot(ax, x, y, label=str(i), linewidth=0.75)

ppl.legend(ax)

fig.savefig('plot_prettyplotlib_default.png')

Creates the following image:

plot_prettyplotlib_default

giffordw commented 10 years ago

Just noticed this myself. The colors show up in the correct way like the documentation examples when using prettyplotlib=0.1.3.

stahlous commented 10 years ago

If you don't pass an Axes object as the first parameter, the colors do work. For example, this will give the expected easy-on-the-eyes colors:

ppl.plot(np.random.normal(size=1000).cumsum())
ppl.plot(np.random.normal(size=1000).cumsum())
ppl.plot(np.random.normal(size=1000).cumsum())

image

The problem is the new version of ppl uses the @pretty decorator to invoke matplotlib's rc_context context manager to set the colors used in each plotting function. However, if you pass an Axes object to the plotting function, it will have been created under a different context and won't pick up the right rc_params.

I'm not sure if it is possible to use the rc_context approach and still allow passing in an Axes object.

giffordw commented 10 years ago

I see what you mean. This seems to suggest that utilizing the colors with ppl in subplots isn't an option.

anntzer commented 10 years ago

A possibilty would be to add a ppl.prettify function which could be called on an Axes instance to reset its parameters, as if it had been created under the prettyplotlib context. Probably with a big fat warning, "no guarantee on results if the axes instance has already been drawn onto".

anntzer commented 10 years ago

Another possibility, which I prefer now, would be to turn ppl.pretty into a ContextDecorator (https://docs.python.org/3/library/contextlib.html#contextlib.ContextDecorator) and require the user to enter the pretty context before instantiating any Axes that are supposed to use ppl colors.