Is there a way to indicate on a plot what different colors for each point and markers represent?

Question:

Is there a way I could add a box (like how I drew in the image below) to indicate what different colors for points and the different markers represent?

Or if there is any other way than adding the boxes, since I want to make it clear for the viewer what the plot exactly means.

Scatter plot with different markers and colors

Asked By: soup

||

Answers:

Yes, check out the documentation for matplotlib.pyplot’s scatter plot.
The marker argument is where you place the shape of the marker, the label argument is what you label the data of that plot in the legend, color is obviously the color of the markers, and s is their size.

To put custom colors for custom conditions, you can use list comprehension to set the color for that specific condition. Then, the easiest way to show all of this in a legend is to create a custom legend:

######################### Mock Data ########################
import numpy as np
import matplotlib.pyplot as plt
time = np.arange(0,10)
y1 = np.random.randint(0, 100, 10)
y2 = np.random.randint(0, 100, 10)
y3 = np.random.randint(0, 100, 10)
df = pd.DataFrame({"time":time, "Star":y1, "Circle":y2, "Square":y3})
#############################################################

# Create custom colors based on conditions
y1Color = ["darkgreen" if x > 75 else "red" if x > 25 else "orange" for x in y1]
y2Color = ["darkgreen" if x > 75 else "red" if x > 25 else "orange" for x in y2]
y3Color = ["darkgreen" if x > 75 else "red" if x > 25 else "orange" for x in y3]

# Create custom legend based on above conditions
legend_elements = [Line2D([0], [0], marker='*', color='w', label='Star > 75', 
                          markerfacecolor='g', markersize=15),
                   Line2D([0], [0], marker='*', color='w', label='Star > 25', 
                          markerfacecolor='r', markersize=15),
                   Line2D([0], [0], marker='*', color='w', label='Star < 25', 
                          markerfacecolor='orange', markersize=15),
                   Line2D([0], [0], marker='o', color='w', label='Circle > 75', 
                          markerfacecolor='g', markersize=15),
                   Line2D([0], [0], marker='o', color='w', label='Circle > 25', 
                          markerfacecolor='r', markersize=15),
                   Line2D([0], [0], marker='o', color='w', label='Circle < 25', 
                          markerfacecolor='orange', markersize=15),
                   Line2D([0], [0], marker='s', color='w', label='Square > 75', 
                          markerfacecolor='g', markersize=15),
                   Line2D([0], [0], marker='s', color='w', label='Square > 25', 
                          markerfacecolor='r', markersize=15),
                   Line2D([0], [0], marker='s', color='w', label='Square < 25', 
                          markerfacecolor='orange', markersize=15),]

# Plot all the points with custom colors and custom legends
plt.scatter(data=df, x="time", y="Star", marker="*", color=y1Color, s=200)
plt.scatter(data=df, x="time", y="Circle", marker="o", color=y2Color, s=200)
plt.scatter(data=df, x="time", y="Square", marker="s", color=y3Color, s=200)
plt.legend(handles=legend_elements)
plt.show()

Output graph:
enter image description here

Slightly shorter/more compact legend:

######################### Mock Data ########################
import numpy as np
import matplotlib.pyplot as plt
time = np.arange(0,10)
y1 = np.random.randint(0, 100, 10)
y2 = np.random.randint(0, 100, 10)
y3 = np.random.randint(0, 100, 10)
df = pd.DataFrame({"time":time, "Star":y1, "Circle":y2, "Square":y3})
#############################################################

# Create custom colors based on conditions
y1Color = ["darkgreen" if x > 75 else "red" if x > 25 else "orange" for x in y1]
y2Color = ["darkgreen" if x > 75 else "red" if x > 25 else "orange" for x in y2]
y3Color = ["darkgreen" if x > 75 else "red" if x > 25 else "orange" for x in y3]

# Create custom legend based on above conditions
legend_elements = [Line2D([0], [0], marker='', color='g', label='> 75', markersize=15),
                   Line2D([0], [0], marker='', color='r', label='> 25', markersize=15),
                   Line2D([0], [0], marker='', color='orange', label='< 25', markersize=15),
                   Line2D([0], [0], marker='*', color='w', label='Star', 
                          markerfacecolor='black', markersize=15),
                   Line2D([0], [0], marker='o', color='w', label='Circle', 
                          markerfacecolor='black', markersize=15),
                   Line2D([0], [0], marker='s', color='w', label='Square',
                          markerfacecolor='black', markersize=15),]

# Plot all the points with custom colors and custom legends
plt.scatter(data=df, x="time", y="Star", marker="*", color=y1Color, s=200)
plt.scatter(data=df, x="time", y="Circle", marker="o", color=y2Color, s=200)
plt.scatter(data=df, x="time", y="Square", marker="s", color=y3Color, s=200)
plt.legend(handles=legend_elements)
plt.show()

Output
enter image description here

Answered By: Michael S.

You can use the markers provided my matplotlib and the label="" function. If you want to label them to represent numbers:

plt.plot(…, marker="", markerfacecolour="", label="")

This ensures markers have different colours and different labels!

Answered By: DialFrost