Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implemented support for 'markevery' in prop_cycle #10713

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

Merged
merged 11 commits into from
Mar 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/users/next_whats_new/markevery_prop_cycle.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Implemented support for axes.prop_cycle property markevery in rcParams
----------------------------------------------------------------------

The Matplotlib ``rcParams`` settings object now supports configuration
of the attribute `axes.prop_cycle` with cyclers using the `markevery`
Line2D object property. An example of this feature is provided at
`~matplotlib/examples/lines_bars_and_markers/markevery_prop_cycle.py`
67 changes: 67 additions & 0 deletions examples/lines_bars_and_markers/markevery_prop_cycle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
=================================================================
Implemented support for prop_cycle property markevery in rcParams
=================================================================

This example demonstrates a working solution to issue #8576, providing full
support of the markevery property for axes.prop_cycle assignments through
rcParams. Makes use of the same list of markevery cases from
https://matplotlib.org/examples/pylab_examples/markevery_demo.html

Renders a plot with shifted-sine curves along each column with
a unique markevery value for each sine curve.
"""
from cycler import cycler
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# Define a list of markevery cases and color cases to plot
cases = [None,
8,
(30, 8),
[16, 24, 30],
[0, -1],
slice(100, 200, 3),
0.1,
0.3,
1.5,
(0.0, 0.1),
(0.45, 0.1)]

colors = ['#1f77b4',
'#ff7f0e',
'#2ca02c',
'#d62728',
'#9467bd',
'#8c564b',
'#e377c2',
'#7f7f7f',
'#bcbd22',
'#17becf',
'#1a55FF']

# Create two different cyclers to use with axes.prop_cycle
markevery_cycler = cycler(markevery=cases)
color_cycler = cycler('color', colors)

# Configure rcParams axes.prop_cycle with custom cycler
custom_cycler = color_cycler + markevery_cycler
mpl.rcParams['axes.prop_cycle'] = custom_cycler

# Create data points and offsets
x = np.linspace(0, 2 * np.pi)
offsets = np.linspace(0, 2 * np.pi, 11, endpoint=False)
yy = np.transpose([np.sin(x + phi) for phi in offsets])

# Set the plot curve with markers and a title
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.6, 0.75])

for i in range(len(cases)):
ax.plot(yy[:, i], marker='o', label=str(cases[i]))
ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)

plt.title('Support for axes.prop_cycle cycler with markevery')

plt.show()
48 changes: 48 additions & 0 deletions lib/matplotlib/rcsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,54 @@ def validate_ps_distiller(s):
_validate_negative_linestyle = ValidateInStrings('negative_linestyle',
['solid', 'dashed'],
ignorecase=True)
def validate_markevery(s):
"""
Validate the markevery property of a Line2D object.

Parameters
----------
s : None, int, float, slice, length-2 tuple of ints,
length-2 tuple of floats, list of ints

Returns
-------
s : None, int, float, slice, length-2 tuple of ints,
length-2 tuple of floats, list of ints

"""
# Validate s against type slice
if isinstance(s, slice):
return s
# Validate s against type tuple
if isinstance(s, tuple):
tupMaxLength = 2
tupType = type(s[0])
if len(s) != tupMaxLength:
raise TypeError("'markevery' tuple must have a length of "
"%d" % (tupMaxLength))
if tupType is int and not all(isinstance(e, int) for e in s):
raise TypeError("'markevery' tuple with first element of "
"type int must have all elements of type "
"int")
if tupType is float and not all(isinstance(e, float) for e in s):
raise TypeError("'markevery' tuple with first element of "
"type float must have all elements of type "
"float")
if tupType is not float and tupType is not int:
raise TypeError("'markevery' tuple contains an invalid type")
# Validate s against type list
elif isinstance(s, list):
if not all(isinstance(e, int) for e in s):
raise TypeError("'markevery' list must have all elements of "
"type int")
# Validate s against type float int and None
elif not isinstance(s, (float, int)):
if s is not None:
raise TypeError("'markevery' is of an invalid type")

return s

validate_markeverylist = _listify_validator(validate_markevery)

validate_legend_loc = ValidateInStrings(
'legend_loc',
Expand Down Expand Up @@ -676,6 +723,7 @@ def validate_hatch(s):
'markersize': validate_floatlist,
'markeredgewidth': validate_floatlist,
'markeredgecolor': validate_colorlist,
'markevery': validate_markeverylist,
'alpha': validate_floatlist,
'marker': validate_stringlist,
'hatch': validate_hatchlist,
Expand Down
30 changes: 30 additions & 0 deletions lib/matplotlib/tests/test_rcparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
validate_cycler,
validate_hatch,
validate_hist_bins,
validate_markevery,
_validate_linestyle)


Expand Down Expand Up @@ -326,6 +327,35 @@ def generate_validator_testcases(valid):
),
'fail': (('aardvark', ValueError),
)
},
{'validator': validate_markevery,
'success': ((None, None),
(1, 1),
(0.1, 0.1),
((1, 1), (1, 1)),
((0.1, 0.1), (0.1, 0.1)),
([1, 2, 3], [1, 2, 3]),
(slice(2), slice(None, 2, None)),
(slice(1, 2, 3), slice(1, 2, 3))
),
'fail': (((1, 2, 3), TypeError),
([1, 2, 0.3], TypeError),
(['a', 2, 3], TypeError),
([1, 2, 'a'], TypeError),
((0.1, 0.2, 0.3), TypeError),
((0.1, 2, 3), TypeError),
((1, 0.2, 0.3), TypeError),
((1, 0.1), TypeError),
((0.1, 1), TypeError),
(('abc'), TypeError),
((1, 'a'), TypeError),
((0.1, 'b'), TypeError),
(('a', 1), TypeError),
(('a', 0.1), TypeError),
('abc', TypeError),
('a', TypeError),
(object(), TypeError)
)
}
)

Expand Down