Using dashed lines is nice because it gives a way to distinguish lines that doesn't rely on the reader being able to perceive differences in color. The trouble is that they only work if the details of the line are all larger than the dash pattern. The documentation for Matplotlib's Axes.plot
function describes how to customize a line's color (with the color
keyword) and how to customize the pattern of dashes (dash
keyword). Is there a way to make the plot alternate between two different selectable colors instead of "there" and "not" with a single call to Axes.plot
?
I can achieve this effect by plotting the same line twice, once with a solid line and then overplotting the same data with the dashed line, but that makes managing the alpha transparency complicated (translucent lines are desirable when there are several intersecting lines on one plot). The black and grey lines in the plot below were generated with these lines of code:
ax.plot(xv1, yv1, marker="None", linestyle="-", color=(0.8, 0.8, 0.8, 1.0))
ax.plot(xv1, yv1, marker="None", linestyle="--", color=(0.0, 0.0, 0.0, 1.0))
Edit: Another reason to desire that this be doable with a single call to Axis.plot
is that it would display an example line correctly when creating a legend (the only remaining drawback I've found of the methods given in the answers).
The usual way to set the line color in matplotlib is to specify it in the plot command. This can either be done by a string after the data, e.g. "r-" for a red line, or by explicitely stating the color argument.
x: X-axis points on the line. y: Y-axis points on the line. linestyle: Change the style of the line.
You can directly specify the dashes length/space using the dashes=(length, interval space) argument inside the plot command.
Experimenting a bit with @WilliamMiller's beautiful answer, this can be extended to more than two colors:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, np.pi*4, 100)
y = np.sin(x+np.pi/2)
z = np.sin(x+np.pi/4)
w = np.sin(x)
plt.plot(x, y, linestyle=(0, (5, 5)), color='gold')
plt.plot(x, y, linestyle=(5, (5, 5)), color='crimson')
plt.plot(x, z, linestyle=(0, (10, 30)), color='blueviolet')
plt.plot(x, z, linestyle=(10, (10, 30)), color='lime')
plt.plot(x, z, linestyle=(20, (10, 30)), color='fuchsia')
plt.plot(x, z, linestyle=(30, (10, 30)), color='coral')
plt.plot(x, w, linestyle=(0, (10, 20)), color='crimson', lw=3)
plt.plot(x, w, linestyle=(10, (10, 20)), color='lime', lw=3)
plt.plot(x, w, linestyle=(20, (10, 20)), color='deepskyblue', lw=3)
plt.show()
This doesn't accomplish what you are asking "with a single call to Axes.plot
", but the desired behavior can be created by using two custom linestyles
- one of which is offset by the width of the other's dash.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, np.pi*4, 100)
y = np.sin(x)
plt.plot(x, y, linestyle=(0, (2, 2)))
plt.plot(x, y, linestyle=(2, (2, 2)))
plt.show()
The linestyle
specification is (offset, (on_off_seq))
where on_off_seq
is a tuple
of one or more values, in pt
s.
In case you want legends on your plot you can do the following:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 2*np.pi, 0.2)
y = np.cos(x)
blue_line, = plt.plot(x, y, linestyle='-', lw=3)
dashed_line, = plt.plot(x, y, linestyle=(2, (2, 2)), lw=3)
plt.legend([(blue_line, dashed_line)], ['data'])
Legends in matplotlib
are very customizable, more interesting examples and information can be seen here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With