How to get alternating colours in dashed line using matplotlib?

Question:

In matplotlib, I want to make a line using matplotlib.pyplot which is alternating black and yellow dashes, and then I want to include that line on the legend. How do I do that?

I could do something like:

from matplotlib import pyplot as plt, gridspec
import numpy as np

grid = gridspec.GridSpec(1,1)
ax = plt.subplot(grid[0,0])

x = np.arange(1,11)
y = x * 2

ax.plot(x, y, '-', color = 'black', linewidth = 1, label = 'my line')
ax.plot(x, y, '--', color = 'yellow')
ax.legend()

plt.show()

but then the line on the legend would appear as a solid black line, rather than as black-and-yellow dashes.

I did look at matplotlib.path_effects but I can’t work out whether it’s possible to achieve what I want; I can outline or shadow the line, but I’m not sure I can overlay a differently-coloured dashed line.

Asked By: John Coxon

||

Answers:

Try this.

from matplotlib import pyplot as plt, gridspec, lines

import numpy as np

grid = gridspec.GridSpec(1,1)
ax = plt.subplot(grid[0,0])

x = np.arange(1,11)
y = x * 2

ax.plot(x, y, '-', color = 'black', linewidth = 5)
ax.plot(x, y, '--', color = 'lawngreen', linewidth = 5)

dotted_line1 = lines.Line2D([], [], linewidth=5, linestyle="--", dashes=(10, 1), color='lawngreen')
dotted_line2 = lines.Line2D([], [], linewidth=5, linestyle="-", dashes=(5, 4), color='black')

plt.legend([(dotted_line1, dotted_line2)], ["My Line"])
plt.show()

i increased the line width so it is clearly visible. As yellow was not that clear in a white background; changed it to green. Sorry about that. You can change colors any time any way 🙂
output

Answered By: Tanmaya Meher

A slight adaptation, if you need an overlay of two dotted lines. Essentially, the same approach as described by Tanmaya Meher can be used, but to get the offsets right, one needs to make small hack in the dashes spec.

Concretely, let’s say you want 1 dot, 1 blank with alternating colors

. . . .

then you can start the first dotted line with dash spec [1,3]. Now the second color should start at pos 2 and then have the same spec, so that they nicely interleave. As there is no explicit way to set an offset, one needs a workaround dash sequence [0,2, 1, 1], that is no point, two blanks, a point, one blank, which sets the desired offset.

import matplotlib.pyplot as plt

from matplotlib.lines import Line2D

color1 = "blue"
color2 = "orange"

fig, ax = plt.subplots()
l1 = Line2D([0,1], [0.5, 0.5], linestyle="dotted", color=color1, lw=10)
l1.set_dashes([0, 2, 1,1])
l2 = Line2D([0,1], [0.5, 0.5], linestyle="dotted", color=color2, lw=10)
l2.set_dashes([1, 3])

ax.add_artist(l1)
ax.add_artist(l2)
ax.legend(handles=((l1,l2),), labels=("label",), handlelength=3)

Dotted line with alternating colors + legend

Answered By: p.py

You could use the gapcolor property. See: https://matplotlib.org/stable/gallery/lines_bars_and_markers/line_demo_dash_control.html

from matplotlib import pyplot as plt, gridspec
import numpy as np

grid = gridspec.GridSpec(1,1)
ax = plt.subplot(grid[0,0])
    
x = np.arange(1,11)
y = x * 2
    
ax.plot(x, y, color = 'black', linewidth = 1, label = 'my line', dashes=[4, 4], gapcolor='yellow')
ax.legend()
    
plt.show()
Answered By: BenJey
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.