5

There are a whole slew of questions on how to set custom dashes in matplotlib lines using Line2D.set_linestyle and Line2D.set_dashes. However, I can not seem to find a way of retrieving the dash pattern after it has been set.

Here is an example of setting the dashes on the main site that I will refer to below: http://matplotlib.org/examples/lines_bars_and_markers/line_demo_dash_control.html. Code is copied here for clarity:

"""
Demo of a simple plot with a custom dashed line.

A Line object's ``set_dashes`` method allows you to specify dashes with
a series of on/off lengths (in points).
"""
import numpy as np
import matplotlib.pyplot as plt


x = np.linspace(0, 10)
line, = plt.plot(x, np.sin(x), '--', linewidth=2)

dashes = [10, 5, 100, 5]  # 10 points on, 5 off, 100 on, 5 off
line.set_dashes(dashes)

plt.show()

There is no line.get_dashes method. Calling line.get_linestyle returns '--'. How do I retrieve the actual dash pattern using MatPlotLib 1.5.1?

UPDATE

For those who care why I am asking: I am trying to create a simple converter from line-style to LaTeX using the dashrule package. The original inspiration comes from this question/answer. It would be nice if I could avoid using linestyle entirely and just get the dashes and linewidth directly.

I have learned to make markers with the tikz package, so it would be nice to eventually be able to add legend elements to axis labels. Given a bit more research and elbow-grease, I hope to combine everything into a PR to MatPlotLib.

UPDATE #2

There appears to be a "private" attribute of Line2D, _dashSeq, which contains the sequence I am looking for. However, the value of this attribute does not change if I set one of the preset styles: e.g.

>>> line.set_linestyle((0, (2, 5, 7, 3)))
>>> line.get_linestyle()  # This seems expected behavior for custom dash
'--'
>>> line._dashSeq         # This is what I want
(2, 5, 7, 3)
>>> line.set_linestyle('--')
>>> line.get_linestyle()  # This reflects reality now
'--'
>>> line._dashSeq         # This no longer does
(2, 5, 7, 3)

The problem is that I now can't tell the two styles (preset vs. custom) apart, so my question still holds.

Community
  • 1
  • 1
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • The quotation was deliberate. – Mad Physicist Jun 27 '16 at 20:29
  • This is a bit of code that has been getting a bunch of thrashing recently (and ends up being coupled into the graphics contexts at draw time). – tacaswell Jun 27 '16 at 23:06
  • So there is no quick-n-dirty way to do this? Also, do you think there is any value to a PR for TeX-based legends that can be placed into labels, etc? I was thinking of either doing that or figuring out a way of getting all the elements of a legend to accept roatation so I can do this: http://stackoverflow.com/q/38002700/2988730. Both appear to be non-trivial though. – Mad Physicist Jun 28 '16 at 04:11
  • @tcaswell. I am thinking of the following workaround for public API, let me know if it is sensible: `_dashSeq` to `None` when one of the preset line styles is set, and add a public `get_dashseq` method to retrieve the style. This way, `get_dashseq` in combination with `get_linestyle` will tell you everything you need about the line style. – Mad Physicist Jun 28 '16 at 14:10
  • This is probably needed + agressively updating the dash pattern as setting either linewidth or linestyle or the dash pattern (see https://github.com/matplotlib/matplotlib/issues/6592) – tacaswell Jun 28 '16 at 15:07

1 Answers1

1

I know this is an old question, but as I was trying to solve a similar issue, I found that the protected attribute has since changed name (to _unscaled_dash_pattern and _dash_pattern), and exactly follows the expected logic. In other words, I think the issue just solved itself.

Notes:

  • I'm using matplotlib 3.7.1.
  • _dash_pattern gets scaled with the line_width. As far as I figured, this is to make sure dots are square.

Example:

>>> line.set_linestyle((0, (2, 5, 7, 3)))
>>> line.get_linestyle()         # Expected behaviour for custom dash
'--'
>>> line._unscaled_dash_pattern  # This is what was needed
(0, (2, 5, 7, 3))
>>> line._dash_pattern           # This is the scaled version (lw=0.5)
(0.0, [1.0, 2.5, 3.5, 1.5])
>>> line.set_linestyle('--')
>>> line.get_linestyle()         # Still expected behaviour
'--'
>>> line._unscaled_dash_pattern  # Now contains updated dash pattern
(0.0, (3.7, 1.6))
JKarouta
  • 66
  • 5