diff --git a/lib/matplotlib/tests/test_lines.py b/lib/matplotlib/tests/test_lines.py index d66509b0ee78..f03058610b16 100644 --- a/lib/matplotlib/tests/test_lines.py +++ b/lib/matplotlib/tests/test_lines.py @@ -217,3 +217,9 @@ def test_marker_as_markerstyle(): assert_array_equal(line2.get_marker().vertices, triangle1.vertices) assert_array_equal(line3.get_marker().vertices, triangle1.vertices) + + +@check_figures_equal() +def test_odd_dashes(fig_test, fig_ref): + fig_test.add_subplot().plot([1, 2], dashes=[1, 2, 3]) + fig_ref.add_subplot().plot([1, 2], dashes=[1, 2, 3, 1, 2, 3]) diff --git a/src/py_converters.cpp b/src/py_converters.cpp index b5e88dd0b2b5..d252da0eda55 100644 --- a/src/py_converters.cpp +++ b/src/py_converters.cpp @@ -226,7 +226,6 @@ int convert_dashes(PyObject *dashobj, void *dashesp) PyObject *dash_offset_obj = NULL; double dash_offset = 0.0; PyObject *dashes_seq = NULL; - Py_ssize_t nentries; if (!PyArg_ParseTuple(dashobj, "OO:dashes", &dash_offset_obj, &dashes_seq)) { return 0; @@ -256,18 +255,17 @@ int convert_dashes(PyObject *dashobj, void *dashesp) return 0; } - nentries = PySequence_Size(dashes_seq); - if (nentries % 2 != 0) { - PyErr_Format(PyExc_ValueError, "dashes sequence must have an even number of elements"); - return 0; - } + Py_ssize_t nentries = PySequence_Size(dashes_seq); + // If the dashpattern has odd length, iterate through it twice (in + // accordance with the pdf/ps/svg specs). + Py_ssize_t dash_pattern_length = (nentries % 2) ? 2 * nentries : nentries; - for (Py_ssize_t i = 0; i < nentries; ++i) { + for (Py_ssize_t i = 0; i < dash_pattern_length; ++i) { PyObject *item; double length; double skip; - item = PySequence_GetItem(dashes_seq, i); + item = PySequence_GetItem(dashes_seq, i % nentries); if (item == NULL) { return 0; } @@ -280,7 +278,7 @@ int convert_dashes(PyObject *dashobj, void *dashesp) ++i; - item = PySequence_GetItem(dashes_seq, i); + item = PySequence_GetItem(dashes_seq, i % nentries); if (item == NULL) { return 0; }