How do you plot with multiple colours for the same point?

Viewed 137

I have some data that I have clustered, and wish to compare it to human-annotations of the same data. The problem I have is that the human-annotator has marked some of the points to have co-existing events (i.e. some points in the space would have two or more labels associated with them). Is there a way that I can show this using matplotlib?

I am thinking something along the lines of the following simplified example:

The main point is to not have the points with events 1 & 2 be classified as some new event '3', but instead to plot the points that have two events, to display these events independently. I assume that this is not an easy task, as there could potentially be more than two coexisting events, but for this example I am only focussing on two.


My plan was to create a one-hot array of shape=(n_points, n_events), and linearly selecting colours for a colourmap by using plt.cm.rainbow which would represent each unique event. But I have gotten stuck here as I do not know how to plot the points with >1 label.

The style in which the points are plotted does not strictly matter (i.e. having the side-by-side colours as I have illustrated is not a requirement), any method of displaying them should be adequate so long as points with multiple events are easily identifiable.

I would post my attempt so far, but as I am stuck on such an early step, it only goes as far as generating a random toy dataset of shape (20, 2), and creating the one-hot array of labels as I had previously mentioned.

2 Answers

You can specify color as well as markerfacecoloralt together with fillstyle='left' in order to obtain a side-by-side color plot. For more information and other styles see this tutorial.

import matplotlib.pyplot as plt
import numpy as np

x = np.sort(np.random.random(size=20))
y = x + np.random.normal(scale=0.2, size=x.shape)

i, j = len(x)//2 - 2, len(x)//2 + 3  # separate the points in left and right

colors = ['#1f77b4', '#ff7f0e']

fig, ax = plt.subplots()
ax.plot(x[:i], y[:i], 'o', color=colors[0], ms=15)  # left part
ax.plot(x[j:], y[j:], 'o', color=colors[1], ms=15)  # right part
ax.plot(x[i:j], y[i:j], 'o',                        # middle part
        fillstyle='left', color=colors[0], markerfacecoloralt=colors[1], ms=15)

plt.show()

Example plot:

Example

If you don't require side-by-side colors you could plot two points on top of each other, using different sizes.

import matplotlib.pyplot as plt
import numpy as np

x = np.sort(np.random.random(size=20))
y = x + np.random.normal(scale=0.2, size=x.shape)

i, j = len(x)//2 - 2, len(x)//2 + 3  # separate the points in left and right

colors = ['#1f77b4', '#ff7f0e']

fig, ax = plt.subplots()
ax.scatter(x[:j], y[:j], c=colors[0], s=100)  # left part (including middle)
ax.scatter(x[j:], y[j:], c=colors[1], s=100)  # right part
ax.scatter(x[i:j], y[i:j], c=colors[1], s=20)  # middle part (using smaller size)

plt.show()

Example plot:

Example

Related