Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I share matplotlib style?

One can load a custom plotting style in matplotlib with something like:

>>> import matplotlib.pyplot as plt
>>> plt.style.use('ggplot')

And I know that I can create my own, http://matplotlib.org/users/style_sheets.html explains how.

Let's say that I create an amazing matplotlib style -- how can I share this with other people? Is there a way to do it with pip/conda or something else appropriate?

The docs include the suggestion to "create custom styles and use them by calling style.use with the path or URL to the style sheet." -- so I guess that I could maintain a link w/ that on some public git repository, and people would just get the most recent style if they put that URL?

like image 673
JBWhitmore Avatar asked Mar 07 '16 18:03

JBWhitmore


People also ask

Where are matplotlib styles stored?

The list of available matplotlib themes is stored in a list called plt. style.

What is style use (' Fivethirtyeight ') in Python?

This shows an example of the "fivethirtyeight" styling, which tries to replicate the styles from FiveThirtyEight.com. import matplotlib.pyplot as plt import numpy as np plt. style. use('fivethirtyeight') x = np. linspace(0, 10) # Fixing random state for reproducibility np.


2 Answers

You could organize your code in a structure like this:

|
└─── setup.py
└─── mplstyles
         style_01.mplstyle
         style_02.mplstyle

Then, in your file setup.py write something like the following:

# -*- coding: utf-8 -*-
import matplotlib as mpl
import glob
import os.path
import shutil
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-install', action='store_true', default=True)
parser.add_argument('-upgrade', action='store_true')
options = parser.parse_args()

#~ # ref  ->  matplotlib/style/core
BASE_LIBRARY_PATH = os.path.join(mpl.get_data_path(), 'stylelib')
STYLE_PATH = os.path.join(os.getcwd(),'mplstyles')
STYLE_EXTENSION = 'mplstyle'
style_files = glob.glob(os.path.join(STYLE_PATH,"*.%s"%(STYLE_EXTENSION)))

for _path_file in style_files:
    _, fname = os.path.split(_path_file)
    dest = os.path.join(BASE_LIBRARY_PATH, fname)
    if not os.path.isfile(dest) and options.install:
        shutil.copy(_path_file, dest)
        print("%s style installed"%(fname))
    elif options.upgrade:
        shutil.copy(_path_file, dest)
        print("%s style upgraded"%(fname))
    elif os.path.isfile(dest):
        print("%s style already exists (use -upgrade to upgrade)"%(fname))
    else:
        pass # ¿?

The code above copy each .mplstyle (or stylesheet) file from "mplstyles" folder to Matplotlib installation directory.

"Install" styles

>> python setup.py -install

"Upgrade" styles

>> python setup.py -upgrade
like image 107
Pedro Jorge De Los Santos Avatar answered Oct 22 '22 23:10

Pedro Jorge De Los Santos


I just had this exact same question. A petty that was not been solved yet. I have found a solution to be able to distribute the style(s) using PyPi (in my case goosempl, also on GitHub).

I have created a Python module of which the mplstyle-files are a part:

|-- setup.py
|-- package_name
|   |-- __init__.py
|   |-- styles
|   |   |-- example.mplstyle

The idea is now:

  1. The .mplstyle file(s) gets packaged with the module.
  2. The module gets installed.
  3. At the end of the installation a small script runs that extracts the .mplstyle file(s) from the newly installed package and writes them to the matplotlib config directory.

Here are the essentials

setup.py

import atexit
from setuptools                 import setup
from setuptools.command.install import install

def _post_install():
    import goosempl
    package_name.copy_style()

class new_install(install):
    def __init__(self, *args, **kwargs):
        super(new_install, self).__init__(*args, **kwargs)
        atexit.register(_post_install)

__version__ = '0.1.0'

setup(
    name              = 'package_name',
    version           = __version__,
    ...
    install_requires  = ['matplotlib>=2.0.0'],
    packages          = ['package_name'],
    cmdclass          = {'install': new_install},
    package_data      = {'package_name/styles':[
        'package_name/styles/example.mplstyle',
    ]},
)

init.py

def copy_style():

  import os
  import matplotlib

  from pkg_resources import resource_string

  files = [
    'styles/example.mplstyle',
  ]

  for fname in files:
    path = os.path.join(matplotlib.get_configdir(),fname)
    text = resource_string(__name__,fname).decode()
    open(path,'w').write(text)

For future reference see these related questions / documentation:

  • Why use package_data and not data_files.

  • Running a post-installation script/command that relies on the installed package

  • Uploading to PyPi

like image 21
Tom de Geus Avatar answered Oct 22 '22 23:10

Tom de Geus