-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add easy style sheet selection #2236
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
Changes from 1 commit
643c74b
3270aa4
d83a03c
c8cc486
455b54c
7769b29
3914089
c3fae2e
a3de231
d56f73e
ec6ce6b
5fdc037
0c7437c
200d2e0
7392ce6
ea63c99
eaa23ee
5f80ca1
f5ecf5e
a8ef5bf
dc291e0
c5b5bb4
7ac26ee
46a725b
d372a35
e714c77
512b77c
17282c8
a6142fc
19e7bed
c604498
0b098e2
7e2bffb
1d87f34
79f83c9
246c348
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
""" | ||
This example demonstrates the "dark_background" style, which uses white for | ||
elements that are typically black (text, borders, etc). Note, however, that not | ||
all plot elements default to colors defined by an rc parameter. | ||
|
||
""" | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
from matplotlib import style | ||
style.use('dark_background') | ||
|
||
|
||
L = 6 | ||
x = np.linspace(0, L) | ||
ncolors = len(plt.rcParams['axes.color_cycle']) | ||
shift = np.linspace(0, L, ncolors, endpoint=False) | ||
for s in shift: | ||
plt.plot(x, np.sin(x + s), 'o-') | ||
plt.xlabel('x-axis') | ||
plt.ylabel('y-axis') | ||
plt.title('title') | ||
|
||
plt.show() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
""" | ||
This example demonstrates the "ggplot" style, which adjusts the style to | ||
emulate ggplot_ (a popular plotting package for R_). | ||
|
||
These settings were shamelessly stolen from [1]_ (with permission). | ||
|
||
.. [1] http://www.huyng.com/posts/sane-color-scheme-for-matplotlib/ | ||
|
||
.. _ggplot: http://had.co.nz/ggplot/ | ||
.. _R: http://www.r-project.org/ | ||
|
||
""" | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
from matplotlib import style | ||
|
||
style.use('ggplot') | ||
|
||
fig, axes = plt.subplots(ncols=2, nrows=2) | ||
ax1, ax2, ax3, ax4 = axes.ravel() | ||
|
||
# scatter plot (Note: `plt.scatter` doesn't use default colors) | ||
x, y = np.random.normal(size=(2, 200)) | ||
ax1.plot(x, y, 'o') | ||
|
||
# sinusoidal lines with colors from default color cycle | ||
L = 2*np.pi | ||
x = np.linspace(0, L) | ||
ncolors = len(plt.rcParams['axes.color_cycle']) | ||
shift = np.linspace(0, L, ncolors, endpoint=False) | ||
for s in shift: | ||
ax2.plot(x, np.sin(x + s), '-') | ||
ax2.margins(0) | ||
|
||
# bar graphs | ||
x = np.arange(5) | ||
y1, y2 = np.random.randint(1, 25, size=(2, 5)) | ||
width = 0.25 | ||
ax3.bar(x, y1, width) | ||
ax3.bar(x+width, y2, width, color=plt.rcParams['axes.color_cycle'][2]) | ||
ax3.set_xticks(x+width) | ||
ax3.set_xticklabels(['a', 'b', 'c', 'd', 'e']) | ||
|
||
# circles with colors from default color cycle | ||
for i, color in enumerate(plt.rcParams['axes.color_cycle']): | ||
xy = np.random.normal(size=2) | ||
ax4.add_patch(plt.Circle(xy, radius=0.3, color=color)) | ||
ax4.axis('equal') | ||
ax4.margins(0) | ||
|
||
plt.show() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
""" | ||
This example demonstrates the "grayscale" style sheet, which changes all colors | ||
that are defined as rc parameters to grayscale. Note, however, that not all | ||
plot elements default to colors defined by an rc parameter. | ||
|
||
""" | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
from matplotlib import style | ||
|
||
|
||
def color_cycle_example(ax): | ||
L = 6 | ||
x = np.linspace(0, L) | ||
ncolors = len(plt.rcParams['axes.color_cycle']) | ||
shift = np.linspace(0, L, ncolors, endpoint=False) | ||
for s in shift: | ||
ax.plot(x, np.sin(x + s), 'o-') | ||
|
||
def image_and_patch_example(ax): | ||
ax.imshow(np.random.random(size=(20, 20)), interpolation='none') | ||
c = plt.Circle((5, 5), radius=5, label='patch') | ||
ax.add_patch(c) | ||
|
||
|
||
style.use('grayscale') | ||
|
||
fig, (ax1, ax2) = plt.subplots(ncols=2) | ||
|
||
color_cycle_example(ax1) | ||
image_and_patch_example(ax2) | ||
|
||
plt.show() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from core import * | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
""" | ||
Core functions and attributes for the matplotlib style library: | ||
|
||
``use`` | ||
Select style sheet to override the current matplotlib settings. | ||
``available`` | ||
List available style sheets. | ||
``library`` | ||
A dictionary of style names and matplotlib settings. | ||
""" | ||
import os | ||
import re | ||
|
||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I hope you don't really need pyplot for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Fixed. |
||
import matplotlib as mpl | ||
|
||
|
||
__all__ = ['use', 'available', 'library'] | ||
|
||
|
||
_here = os.path.abspath(os.path.dirname(__file__)) | ||
BASE_LIBRARY_PATH = os.path.join(_here, 'stylelib') | ||
# Users may want multiple library paths, so store a list of paths. | ||
USER_LIBRARY_PATHS = [os.path.join('~', '.matplotlib', 'stylelib')] | ||
STYLE_FILE_PATTERN = re.compile('([A-Za-z._-]+).mplrc$') | ||
|
||
|
||
def use(name): | ||
"""Use matplotlib rc parameters from a pre-defined name or from a file. | ||
|
||
Parameters | ||
---------- | ||
name : str or list of str | ||
Name of style. For list of available styles see `style.available`. | ||
If given a list, each style is applied from first to last in the list. | ||
""" | ||
if np.isscalar(name): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have cbook.is_scalar() |
||
name = [name] | ||
for s in name: | ||
plt.rcParams.update(library[s]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would benefit from a more helpful error message if |
||
|
||
|
||
def load_base_library(): | ||
"""Load style library defined in this package.""" | ||
library = dict() | ||
library.update(read_style_directory(BASE_LIBRARY_PATH)) | ||
return library | ||
|
||
|
||
def iter_user_libraries(): | ||
for stylelib_path in USER_LIBRARY_PATHS: | ||
stylelib_path = os.path.expanduser(stylelib_path) | ||
if os.path.exists(stylelib_path) and os.path.isdir(stylelib_path): | ||
yield stylelib_path | ||
|
||
|
||
def update_user_library(library): | ||
"""Update style library with user-defined rc files""" | ||
for stylelib_path in iter_user_libraries(): | ||
styles = read_style_directory(stylelib_path) | ||
update_nested_dict(library, styles) | ||
return library | ||
|
||
|
||
def iter_style_files(style_dir): | ||
"""Yield file path and name of styles in the given directory.""" | ||
for path in os.listdir(style_dir): | ||
filename = os.path.basename(path) | ||
match = STYLE_FILE_PATTERN.match(filename) | ||
if match: | ||
path = os.path.abspath(os.path.join(style_dir, path)) | ||
yield path, match.groups()[0] | ||
|
||
|
||
def read_style_directory(style_dir): | ||
"""Return dictionary of styles defined in `style_dir`.""" | ||
styles = dict() | ||
for path, name in iter_style_files(style_dir): | ||
styles[name] = mpl.rc_params_from_file(path) | ||
return styles | ||
|
||
|
||
def update_nested_dict(main_dict, new_dict): | ||
"""Update nested dict (only level of nesting) with new values. | ||
|
||
Unlike dict.update, this assumes that the values of the parent dict are | ||
dicts (or dict-like), so you shouldn't replace the nested dict if it | ||
already exists. Instead you should update the sub-dict. | ||
""" | ||
# update named styles specified by user | ||
for name, rc_dict in new_dict.iteritems(): | ||
if name in main_dict: | ||
# FIXME: This is currently broken because rc_params_from_file fills | ||
# in all settings so the update overwrites all values. | ||
main_dict[name].update(rc_dict) | ||
else: | ||
main_dict[name] = rc_dict | ||
return main_dict | ||
|
||
|
||
# Load style library | ||
# ================== | ||
_base_library = load_base_library() | ||
library = update_user_library(_base_library) | ||
available = library.keys() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Set black background default line colors to white. | ||
|
||
lines.color: white | ||
patch.edgecolor: white | ||
|
||
text.color: white | ||
|
||
axes.facecolor: black | ||
axes.edgecolor: white | ||
axes.labelcolor: white | ||
axes.color_cycle: 8dd3c7, feffb3, bfbbd9, fa8174, 81b1d2, fdb462, b3de69, bc82bd, ccebc4, ffed6f | ||
|
||
xtick.color: white | ||
ytick.color: white | ||
|
||
grid.color: white | ||
|
||
figure.facecolor: black | ||
figure.edgecolor: black | ||
|
||
savefig.facecolor: black | ||
savefig.edgecolor: black | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# from http://www.huyng.com/posts/sane-color-scheme-for-matplotlib/ | ||
|
||
patch.linewidth: 0.5 | ||
patch.facecolor: 348ABD # blue | ||
patch.edgecolor: EEEEEE | ||
patch.antialiased: True | ||
|
||
font.size: 10.0 | ||
|
||
axes.facecolor: E5E5E5 | ||
axes.edgecolor: white | ||
axes.linewidth: 1 | ||
axes.grid: True | ||
axes.titlesize: x-large | ||
axes.labelsize: large | ||
axes.labelcolor: 555555 | ||
axes.axisbelow: True # grid/ticks are below elements (eg lines, text) | ||
|
||
axes.color_cycle: E24A33, 348ABD, 988ED5, 777777, FBC15E, 8EBA42, FFB5B8 | ||
# E24A33 : red | ||
# 348ABD : blue | ||
# 988ED5 : purple | ||
# 777777 : gray | ||
# FBC15E : yellow | ||
# 8EBA42 : green | ||
# FFB5B8 : pink | ||
|
||
xtick.color: 555555 | ||
xtick.direction: out | ||
|
||
ytick.color: 555555 | ||
ytick.direction: out | ||
|
||
grid.color: white | ||
grid.linestyle: - # solid line | ||
|
||
figure.facecolor: white | ||
figure.edgecolor: 0.50 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Set all colors to grayscale | ||
# Note: strings of float values are interpreted by matplotlib as gray values. | ||
|
||
|
||
lines.color: black | ||
patch.facecolor: gray | ||
patch.edgecolor: black | ||
|
||
text.color: black | ||
|
||
axes.facecolor: white | ||
axes.edgecolor: black | ||
axes.labelcolor: black | ||
# black to light gray | ||
axes.color_cycle: 0.00, 0.40, 0.60, 0.70 | ||
|
||
xtick.color: black | ||
ytick.color: black | ||
|
||
grid.color: black | ||
|
||
figure.facecolor: 0.75 | ||
figure.edgecolor: white | ||
|
||
image.cmap: gray | ||
|
||
savefig.facecolor: white | ||
savefig.edgecolor: white | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason that this file doesn't just contain all the contents of core, instead of wildcard importing them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a matter of style, I guess. I prefer
__init__.py
modules to be fairly lightweight, but if that's frowned upon, I'm fine with changing it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, aren't we doing the dot-style imports now? I also still don't like the import *.