matplotlib/matplotlib · error · TypeError
'markevery' tuple must be pair of ints or of floats
Error message
'markevery' tuple must be pair of ints or of floats
What it means
validate_markevery() runs over the 'markevery' key of axes.prop_cycle (via validate_markeverylist). A tuple markevery must be a pair of exactly two elements and homogeneous: both int (subsample start/stride) or both float (start/stop fraction). A 2-tuple mixing int and float, or any tuple of another length, raises this TypeError.
Source
Thrown at lib/matplotlib/rcsetup.py:596
Parameters
----------
s : None, int, (int, int), slice, float, (float, float), or list[int]
Returns
-------
None, int, (int, int), slice, float, (float, float), or list[int]
"""
# Validate s against type slice float int and None
if isinstance(s, (slice, float, int, type(None))):
return s
# Validate s against type tuple
if isinstance(s, tuple):
if (len(s) == 2
and (all(isinstance(e, int) for e in s)
or all(isinstance(e, float) for e in s))):
return s
else:
raise TypeError(
"'markevery' tuple must be pair of ints or of floats")
# Validate s against type list
if isinstance(s, list):
if all(isinstance(e, int) for e in s):
return s
else:
raise TypeError(
"'markevery' list must have all elements of type int")
raise TypeError("'markevery' is of an invalid type")
validate_markeverylist = _listify_validator(validate_markevery)
def validate_bbox(s):
if isinstance(s, str):
s = s.lower()
if s == 'tight':View on GitHub (pinned to b379c1b69e)
Solutions
- Use an int pair for index-based subsampling: (0, 10) = every 10th marker starting at index 0
- Or a float pair for fractional positions: (0.1, 0.5) = markers between 10%-50% of the line
- Normalize mixed pairs before building the cycler: tuple(int(x) for x in pair) or tuple(float(x) for x in pair)
Example fix
# before
from cycler import cycler
import matplotlib.pyplot as plt
plt.rc('axes', prop_cycle=cycler(markevery=[(0, 0.1)])) # mixed types
# after
plt.rc('axes', prop_cycle=cycler(markevery=[(0.0, 0.1)])) Defensive patterns
Strategy: type-guard
Validate before calling
def valid_markevery(s):
if isinstance(s, (slice, float, int, type(None))):
return True
if isinstance(s, tuple):
return (len(s) == 2
and (all(type(e) is int for e in s)
or all(type(e) is float for e in s)))
if isinstance(s, list):
return all(type(e) is int for e in s)
return False
assert valid_markevery((0, 10))
assert not valid_markevery((0, 0.1)) Type guard
def is_markevery_pair(v) -> bool:
return (isinstance(v, tuple) and len(v) == 2
and (all(isinstance(e, int) and not isinstance(e, bool) for e in v)
or all(isinstance(e, float) for e in v))) Try / catch
from cycler import cycler
try:
plt.rc('axes', prop_cycle=cycler(markevery=[me]))
except TypeError as e:
me = (int(me[0]), int(me[1]))
plt.rc('axes', prop_cycle=cycler(markevery=[me])) Prevention
- Keep markevery pairs homogeneous: (int, int) or (float, float), never mixed
- Normalize numeric config values to int or float explicitly before building cyclers
- Remember pairs are length-2 only; longer tuples are not supported
When it happens
Trigger: Building plt.rc('axes', prop_cycle=cycler(markevery=[(0, 10)])) correctly, but [(0, 0.1)], [(0.1, 10)], or [(0, 1, 2)] raise. Note bool counts as int, so (True, 5) slips through.
Common situations: Converting an interval spec from user config into a markevery tuple without normalizing types; mixing a 0-based index with a fraction in one pair after refactoring.
Related errors
- 'markevery' list must have all elements of type int
- Cannot put cycle reference ({s!r}) in prop_cycler
- 'markevery' is of an invalid type
- Object is not a string or Cycler instance: {s!r}
- Cannot supply both positional and keyword arguments to this
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/f359a59177f8b40f.
Report an issue: GitHub.