I want to plot a line with dashes of different colours. Here is my current solution:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm
def plotmulticolor(x, y, cmap, axis, dashes=100):
norm = BoundaryNorm(np.arange(cmap.N + 1) - 0.5, cmap.N)
xp = []
yp = []
cp = []
for i in range(len(x) - 1):
xi = [x[i], x[i + 1]]
yi = [y[i], y[i + 1]]
d = np.sqrt(np.diff(ax.transLimits.transform(xi)) ** 2 + np.diff(ax.transLimits.transform(yi)) ** 2)
n = int(d / np.sqrt(2) * dashes)
xp += np.linspace(xi[0], xi[1], n).tolist()
yp += np.linspace(yi[0], yi[1], n).tolist()
cp += np.tile(np.arange(cmap.N), int(np.ceil(n / cmap.N)))[:n - 1].tolist()
points = np.array([xp, yp]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, cmap=cmap, norm=norm)
lc.set_array(np.array(cp))
return ax.add_collection(lc)
fig, ax = plt.subplots()
ax.set_xlim([0, 10])
ax.set_ylim([0, 10])
plotmulticolor([0, 5, 10], [0, 1, 10], ListedColormap(["r", "b", "g"]), axis=ax)
plt.show()
which gives what I want:
The problem is however that I hand-compute the number of dashes, which is heuristic, but mostly problematic as it requires a choice of appropriate scale. Currently I assume that I set the axes limits before, which gives me a scale, and I compute the dash size from it.
My question now is: is there a cleverer way that avoids the somewhat heuristic computation of the dash-size?
