I'm attempting to subclass matplotlib.lines.Line2D
to create lines whose width and dash spacings are in the same coordinates as the data being plotted. I've expanded on this answer to try to support dashed lines (with the dash spacings also being in data units) and have the following code currently:
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
class LineDataUnits(Line2D):
"""
A Line2D object, but with the linewidth and dash properties defined in data coordinates.
"""
def __init__(self, *args, **kwargs):
_lw_data = kwargs.pop("linewidth", 1)
_dashes_data = kwargs.pop("dashes", (1,))
super().__init__(*args, **kwargs)
self._lw_data = _lw_data
self._dashes_data = _dashes_data
self._dashOffset = 0
def _get_lw(self):
if self.axes is not None:
ppd = 72./self.axes.figure.dpi
trans = self.axes.transData.transform
return ((trans((1, self._lw_data))-trans((0, 0)))*ppd)[1]
else:
return 1
def _set_lw(self, lw):
self._lw_data = lw
def _get_dashes(self):
if self.axes is not None:
ppd = 72./self.axes.figure.dpi
trans = self.axes.transData.transform
return tuple([((trans((1, dash_data))-trans((0, 0)))*ppd)[1] for dash_data in self._dashes_data])
else:
return tuple((1, 0))
def _set_dashes(self, dashes):
self._dashes_data = dashes
_linewidth = property(_get_lw, _set_lw)
_dashSeq = property(_get_dashes, _set_dashes)
if __name__ == "__main__":
fig, ax = plt.subplots()
line1 = Line2D([0, 10], [3, 3], linewidth=10, color="blue", dashes=(3, 3), dash_capstyle="round")
line2 = LineDataUnits([0, 10], [6, 6], linewidth=0.5, color="red", dashes=(1, 1), dash_capstyle="round")
print("dash_capstyle:", line2.get_dash_capstyle())
ax.add_line(line1)
ax.add_line(line2)
ax.set_xticks(range(10))
ax.grid()
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
plt.show()
Which yields the following graph:
When I zoom in and out, the dash spacings do seem to remain constant in the data units, however as you can see in the graph, their values are not calculated correctly. Furthermore, it appears setting the dash_capstyle
parameter in this class seems to have no effect.
Any help would be greatly appreciated.