Matplotlib Markers
Learn how to use and customize Matplotlib markers in Python plots. Covers all marker styles, size, color, fill, and per-point customization.
Markers are the symbols Matplotlib draws at each data point in a plot. Choosing the right marker style — and knowing how to resize, recolor, and fill it — can make the difference between a cluttered chart and one that communicates clearly. This page covers every marker style available in Matplotlib, how to customize their appearance, and when to use plot() versus scatter() for per-point control.
What is a Marker in Matplotlib?
A marker is a shape rendered at each (x, y) coordinate in a plot. You control which shape is used with the marker parameter (or as part of a format string). Markers are separate from the line connecting data points — you can show one without the other.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 5, 3, 7, 4]
# Line with markers
plt.plot(x, y, marker='o')
# Markers only — no connecting line
plt.plot(x, y, marker='s', linestyle='None')
plt.show()All Built-in Marker Styles
Matplotlib ships with more than 30 built-in marker codes. The table below lists the most commonly used ones.
| Marker code | Shape |
|---|---|
'o' | Circle |
's' | Square |
'D' | Diamond |
'd' | Thin diamond |
'^' | Triangle (up) |
'v' | Triangle (down) |
'<' | Triangle (left) |
'>' | Triangle (right) |
'p' | Pentagon |
'h' | Hexagon 1 |
'H' | Hexagon 2 |
'8' | Octagon |
'*' | Star |
'+' | Plus |
'x' | Cross |
'X' | Filled cross |
| `' | '` |
'_' | Horizontal line |
'.' | Point (small dot) |
',' | Pixel |
'1' | Tri-down |
'2' | Tri-up |
'3' | Tri-left |
'4' | Tri-right |
'None' or '' | No marker |
To see every marker at once, you can iterate over matplotlib.markers.MarkerStyle.markers:
import matplotlib.pyplot as plt
import matplotlib.markers as mmarkers
print(list(mmarkers.MarkerStyle.markers.keys()))Using Markers in a Line Plot
The plot() function accepts a marker argument. It applies the same marker to every data point.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 15, 25, 30]
plt.plot(x, y, marker='o')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Line plot with circle markers')
plt.show()Using a Format String
Instead of separate keyword arguments, you can combine the line style, color, and marker into a single format string: '[color][marker][linestyle]'.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 15, 25, 30]
# Red circles connected by a dashed line
plt.plot(x, y, 'ro--')
plt.title('Format string: red circles, dashed line')
plt.show()Common format string components:
| Color | Marker | Line style |
|---|---|---|
'r' red | 'o' circle | '-' solid |
'g' green | 's' square | '--' dashed |
'b' blue | '^' triangle | ':' dotted |
'k' black | '*' star | '-.' dash-dot |
'm' magenta | '+' plus | 'None' no line |
Customizing Marker Appearance
Matplotlib exposes four keyword arguments for fine-grained marker control:
| Parameter | What it controls |
|---|---|
markersize (or ms) | Marker diameter in points |
markerfacecolor (or mfc) | Fill color of the marker |
markeredgecolor (or mec) | Color of the marker border |
markeredgewidth (or mew) | Width of the marker border in points |
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 15, 25, 30]
plt.plot(
x, y,
marker='o',
markersize=12,
markerfacecolor='gold',
markeredgecolor='navy',
markeredgewidth=2,
)
plt.title('Customized circle markers')
plt.show()Hollow Markers
Set markerfacecolor='none' (lowercase string) to draw only the border, creating a hollow marker:
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [3, 1, 4, 1, 5]
plt.plot(x, y, marker='s', markersize=14, markerfacecolor='none', markeredgecolor='steelblue', markeredgewidth=2)
plt.title('Hollow square markers')
plt.show()Fill Style
The fillstyle parameter controls which portion of the marker is filled. Valid values are 'full', 'left', 'right', 'bottom', 'top', and 'none'.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 4, 3, 5, 1]
plt.plot(x, y, marker='o', markersize=16, fillstyle='left', markerfacecolor='crimson', markeredgecolor='black')
plt.title('Half-filled circle markers (fillstyle="left")')
plt.show()Per-Point Marker Control with scatter()
plot() applies a uniform marker to the entire line. When you need each point to have a different size or color — for example, to encode a third variable — use scatter() instead.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 15, 25, 30]
sizes = [40, 100, 200, 80, 160] # area in points²
colors = [0.2, 0.5, 0.8, 0.3, 0.9] # mapped through colormap
sc = plt.scatter(x, y, s=sizes, c=colors, cmap='plasma', edgecolors='black')
plt.colorbar(sc, label='Value')
plt.title('Per-point size and color with scatter()')
plt.show()Key differences between plot() and scatter() for markers:
| Feature | plot() | scatter() |
|---|---|---|
| Marker shape | Same for all points | Same for all points |
| Marker size | Uniform | Per-point (s array) |
| Marker color | Uniform | Per-point (c array + colormap) |
| Performance on large datasets | Faster | Slower |
Multiple Data Series with Different Markers
Use separate plot() calls to assign a distinct marker to each series, then add a legend:
import matplotlib.pyplot as plt
months = [1, 2, 3, 4, 5, 6]
product_a = [120, 135, 110, 150, 140, 160]
product_b = [80, 95, 100, 90, 115, 130]
product_c = [60, 70, 65, 85, 90, 95]
plt.plot(months, product_a, marker='o', label='Product A')
plt.plot(months, product_b, marker='s', label='Product B')
plt.plot(months, product_c, marker='^', label='Product C')
plt.xlabel('Month')
plt.ylabel('Units sold')
plt.title('Monthly sales by product')
plt.legend()
plt.show()Markers Without a Connecting Line
Passing linestyle='None' (or ls='None') removes the line and leaves only the markers — effectively a scatter plot using plot().
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [3, 1, 4, 1, 5, 9, 2, 6]
plt.plot(x, y, marker='D', linestyle='None', color='darkorange', markersize=10)
plt.title('Diamond markers, no line')
plt.show()This pattern is useful when the order of data points matters (preserving the original x ordering) but you do not want a line implying a continuous trend.
Practical Tips
- Match the marker to the data density. Use small markers (
'.'or',') when plotting thousands of points; larger shapes ('o','s') for a handful of measurements. - Ensure contrast. On white backgrounds, dark
markeredgecoloron a lightmarkerfacecolorkeeps each point visible even at small sizes. - Avoid overloading a single plot. More than five distinct marker shapes in one chart makes the legend hard to read — consider subplots or color alone.
- Use
scatter()for third-variable encoding. Size or color arrays mapped to a colormap communicate an additional dimension without adding more series to the legend.
Related Topics
- Matplotlib Line Plots — customize line style alongside your markers
- Matplotlib Scatter Plot — per-point size and color control
- Matplotlib Labels — add axis labels and titles to your charts
- Matplotlib Plotting Overview — a tour of all major plot types