Is there a list of line styles in matplotlib?

I'm writing a script that will do some plotting. I want it to plot several data series, each with its unique line style (not color). I can easily iterate through a list, but is there such a list already available in python?

130641 次浏览

According to the doc you could find them by doing this :

from matplotlib import lines
lines.lineStyles.keys()
>>> ['', ' ', 'None', '--', '-.', '-', ':']

You can do the same with markers

EDIT: In the latest versions, there are still the same styles, but you can vary the space between dots/lines.

plot documentation

https://matplotlib.org/3.5.3/api/markers_api.html (previously https://matplotlib.org/1.5.3/api/pyplot_api.html#matplotlib.pyplot.plot) has a list of line + marker styles:

character description
'-'       solid line style
'--'      dashed line style
'-.'      dash-dot line style
':'       dotted line style
'.'       point marker
','       pixel marker
'o'       circle marker
'v'       triangle_down marker
'^'       triangle_up marker
'<'       triangle_left marker
'>'       triangle_right marker
'1'       tri_down marker
'2'       tri_up marker
'3'       tri_left marker
'4'       tri_right marker
's'       square marker
'p'       pentagon marker
'*'       star marker
'h'       hexagon1 marker
'H'       hexagon2 marker
'+'       plus marker
'x'       x marker
'D'       diamond marker
'd'       thin_diamond marker
'|'       vline marker
'_'       hline marker

Since this is part of the pyplot.plot docstring, you can also see it from the terminal with:

import matplotlib.pyplot as plt
help(plt.plot)

From my experience it is nice to have the colors and markers in a list so I can iterate through them when plotting.

Here's how I obtain the list of such things. It took some digging.

import matplotlib
colors_array = matplotlib.colors.cnames.keys()
markers_array = matplotlib.markers.MarkerStyle.markers.keys()

In python3 the .keys() method returns a dict_keys object and not a list. You need to pass the results to list() to be able to index the array as you could in python2. e.g. this SO question

So to create iterable arrays for lines, colors and markers you can use something like.

import matplotlib
colors_array = list(matplotlib.colors.cnames.keys())
lines_array = list(matplotlib.lines.lineStyles.keys())
markers_array = list(matplotlib.markers.MarkerStyle.markers.keys())

I'm not directly answering the question of accessing a list, but it's useful to have one more alternative on this page: there is an additional way to generate dashed line styles.

You can generate lines between A and B with transversal stripes like

A ||||||||||||||||||||||||||||||||||||||||||||||| B

A || || || || || || || || || || || || || || || || B

A | | | | | | | | | | | | | | | | | | | | | | | | B

by increasing the width of your line and specifying a custom dash pattern:

ax.plot(x, y, dashes=[30, 5, 10, 5])

The documentation for matplotlib.lines.Line2D says this about set_dashes(seq):

Set the dash sequence, sequence of dashes with on off ink in points. If seq is empty or if seq = (None, None), the linestyle will be set to solid.

ACCEPTS: sequence of on/off ink in points

I think it could have been said better: as it paints the line, the sequence of numbers specifies how many points are painted along the line, then how many points are left out (in case there are two numbers), how many are painted, how many are unpainted (in case of four numbers in the sequence). With four numbers, you can generate a dash‒dotted line: [30, 5, 3, 5] gives a 30-point-long dash, a 5-point gap, a 3-point dash (a dot), and a 5-point gap. Then it repeats.

This page of the documentation explains this possibility. Look here for two different ways of doing it.

You can copy the dictionary from the Linestyle example:

from collections import OrderedDict


linestyles = OrderedDict(
[('solid',               (0, ())),
('loosely dotted',      (0, (1, 10))),
('dotted',              (0, (1, 5))),
('densely dotted',      (0, (1, 1))),


('loosely dashed',      (0, (5, 10))),
('dashed',              (0, (5, 5))),
('densely dashed',      (0, (5, 1))),


('loosely dashdotted',  (0, (3, 10, 1, 10))),
('dashdotted',          (0, (3, 5, 1, 5))),
('densely dashdotted',  (0, (3, 1, 1, 1))),


('loosely dashdotdotted', (0, (3, 10, 1, 10, 1, 10))),
('dashdotdotted',         (0, (3, 5, 1, 5, 1, 5))),
('densely dashdotdotted', (0, (3, 1, 1, 1, 1, 1)))])

You can then iterate over the linestyles

fig, ax = plt.subplots()


X, Y = np.linspace(0, 100, 10), np.zeros(10)
for i, (name, linestyle) in enumerate(linestyles.items()):
ax.plot(X, Y+i, linestyle=linestyle, linewidth=1.5, color='black')


ax.set_ylim(-0.5, len(linestyles)-0.5)


plt.show()

Or you just take a single linestyle out of those,

ax.plot([0,100], [0,1], linestyle=linestyles['loosely dashdotdotted'])