Skip to content Skip to sidebar Skip to footer

How Do I Have Matplotlib Plot Different Edgecolors For Different Classes With Facecolors='none'?

I'm trying to make a plot like this which means facecolors='none' This code X, y = make_circles(100, factor=.1, noise=.1) plt.scatter(X[:, 0], X[:, 1], s=50, cmap='autumn', faceco

Solution 1:

Edgecolors is not like c

The cmap parameter will only be applied to c. But c will overwrite facecolors="none" so we don't want to use it.

Unlike the parameter c, the parameter edgecolors must receive values that are directly interpretable as colors, meaning rgb or rgba values, color_strings... or any format specified in this matplotlib colors page.

You can pass y to a cmap :

import matplotlib.pyplot as plt
cmap = plt.get_cmap("winter")
colors = cmap(y * 255) # or cmap(y.astype(float))
print(colors)
# > array([[1., 1., 0., 1.], # RGBA values
#          [1., 1., 0., 1.],
#          [1., 1., 0., 1.],
#          [1., 0., 0., 1.],
#                ...       ])
plt.scatter(X[:, 0], X[:, 1], s=50, facecolors="none", edgecolors=colors)

Notice that you have to pass integers between 0 and 255 or floats between 0. and 1., to spread the colors along the cmap.

Plot with cmap

You can also infer colors from a dictionary you designed yourself :

color_dict = {0: "r", 1: "b"}
colors=tuple(map(color_dict.get, y))
print(colors)
# > ('b', 'b', 'b', 'r', ...)
plt.scatter(X[:, 0], X[:, 1], s=50, facecolors="none", edgecolors=colors)

Plot with dict

Markers are not like colors

You can't specify different markers in a single scatter call, because it only accepts a single representation of a MarkerStyle (as an instance of the class or as a string).

That means that you have to call scatter as many times as the count of different markers you want.

Furthermore, at the moment, you can't make use of edgecolor with the + markerstyle.

The easiest way would be to mask your data by color :

red_mask = y==0
print(red_mask)
# > [False, False, False, True ...]
plt.scatter(X[red_mask, 0], X[red_mask, 1], s=50, facecolors="none", edgecolors="r")
plt.scatter(X[~red_mask, 0], X[~red_mask, 1], s=50, marker="+", c="b")

Plot with markerstyle

Another solution would be to plot each point, but it's less elegant IMO :

for X_x, X_y, clas in zip(X[:, 0], X[:, 1], y) :
    if clas == 1:
        plt.scatter(X_x, X_y, c="b", marker="+")
    else:
        plt.scatter(X_x, X_y, facecolors="none", edgecolor="r", marker="o", )
# Same resulting plot

Post a Comment for "How Do I Have Matplotlib Plot Different Edgecolors For Different Classes With Facecolors='none'?"