TinyTheBrontosaurus
TinyTheBrontosaurus

Reputation: 4800

Parallel line styles in matplotlib

I'm looking to draw advanced LineStyle's using MatPlotLib, specifically where a single plotted line with have a LineStyle such that there are parallel lines. Below is an artists rendition. Ideally, the parallel linestyle would be equidistant throughout the plot (in the example, it gets a little tight around corners)

enter image description here

Note: It looks like path_effects is close but that appears to do a static x,y offset relative to the line. the offset should be relative to the direction of the line.

EDIT: I'm looking something closer to the following, where a scatterplot essentially has the directionality built into the linestyle. See the attached where the the dashed line is always on the "right side" (or starboard) side of the trajectory.

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(dpi=100)

v = []
X = np.array([0, 1, 1, 0, 0.5])
Z = np.array([1, 1, 0, 0, 0.5])

ax.plot(X, Z, 'r')


offset = 0.01
X = np.array([0, 1 - offset, 1 - offset, 0 + offset*2, 0.5 + offset*2])
Z = np.array([1 - offset, 1 - offset, 0 + offset, 0 + offset, 0.5])
ax.plot(X, Z, 'r--')
plt.show()

enter image description here

Does anyone know of a way to do this?

For reference, the type of lines I will be plotting will look like the example below (with with double lines), so simply plotting the line twice with a simple x or y offset will not do the trick.

enter image description here

Upvotes: 0

Views: 421

Answers (1)

Z-Y.L
Z-Y.L

Reputation: 1769

You can use ScaledTranslation to create an offset transform, then apply the offset transform to the original transform. The example code is:

import matplotlib.pyplot as plt
from matplotlib.transforms import ScaledTranslation
import numpy as np

fig, ax = plt.subplots(dpi=100)

X = np.linspace(0, 2*np.pi, 100)
Y = 0.5*X - 1
Z = np.cos(X)

ax.plot(X, Y, 'b')
ax.plot(X, Z, 'r')


points= 1 / 72
dx, dy = 0, -10*points
offset = ScaledTranslation(dx, dy, fig.dpi_scale_trans)
ax.plot(X, Y, 'b--', transform=ax.transData + offset)
ax.plot(X, Z, 'r--', transform=ax.transData + offset)

For example, ax.plot(X, Y, 'b--', transform=ax.transData + offset) means to first plot the line in the data coordinates (ax.transData) and then shifted by dx and dy points using fig.dpi_scale_trans.

The obtained figure:

enter image description here

Upvotes: 3

Related Questions