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

Add figure decorator. #46

Open
jfear opened this issue Oct 24, 2017 · 4 comments
Open

Add figure decorator. #46

jfear opened this issue Oct 24, 2017 · 4 comments

Comments

@jfear
Copy link
Contributor

jfear commented Oct 24, 2017

  • lcdblib version: NA
  • Python version: NA
  • Operating System: NA

Description

I have been thinking about streamlining my plotting workflow. I am proposing a decorator to plot functions allow outputting different contexts and formats.

What I Did

My current decorator:

from functools import wraps

def make_figs(fname=None, styles=None, formats=None):
    def _plot_all(func, styles=styles, formats=formats):
        @wraps(func)
        def wrapper(*args, styles=styles, formats=formats, **kwargs):
            def plot_style(style, formats):
                if isinstance(formats, str):
                    formats = [formats]
                elif formats is None:
                    formats = ['png', 'eps']
                
                with plt.style.context('seaborn-' + style):
                    fn = fname + '_' + style
                    func(*args,  **kwargs)
                    plt.tight_layout()
                    if style != 'notebook':
                        for f in formats:
                            plt.savefig('{}.{}'.format(fn, f))
                        plt.close()
                        
            if isinstance(styles, str):
                styles = [styles]
            elif styles is None:
                styles = ['notebook', 'talk', 'poster', 'paper']
                
            for style in styles:
                plot_style(style, formats)

        return wrapper
    return _plot_all

To use you can call it like so:

@make_figs(fname='test_plot', styles=['notebook', 'poster', 'paper'], formats=['png', 'svg'])
def plot(df):
    fig, ax = plt.subplots(1, 1)
    df.plot('X', 'Y', kind='scatter', ax=ax)
    ax.set_title('test')
    return fig

This would then output:

  • test_plot_poster.png
  • test_plot_poster.svg
  • test_plot_paper.png
  • test_plot_paper.svg

The notebook style is displayed.

@daler you probably already have something that does this kind of thing. Just seeing if it is generally useful and should be be added to lcdblib. Or if I should just keep it in my personal library.

@daler
Copy link
Contributor

daler commented Oct 24, 2017

Oooo that looks really nice. I generally have separate code blocks for different styles (or separate modules entirely just for manuscript figures). But I'd start using this instead.

@jfear
Copy link
Contributor Author

jfear commented Oct 24, 2017

I would be curious how you do figures, it would be nice to have some clean solution.

@daler
Copy link
Contributor

daler commented Oct 24, 2017

I generally have big blocks of custom code depending on the figure -- not sure there's a general solution there. When saving PNG or PDF, I currently just duplicate the savefig() line, adjusting extension as needed. But this decorator just adds functionality to whatever custom function you have, so I think it's a pretty clean solution.

@jfear
Copy link
Contributor Author

jfear commented Oct 24, 2017

Cool, I am going to play with it for one of my projects. If it works out I will go ahead and add to lcdblib.

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

No branches or pull requests

2 participants