How to create a scatter plot with two colors per dot?

谁说胖子不能爱 提交于 2020-06-27 18:00:13

问题


I'm trying to plot both the ground-truth and my classification simultaneously in matplotlib.

Currently, I only plot the groud-truth, after applying tsne on the feature space and adding the edges using the following code

from matplotlib.collections import LineCollection
cols=['rgbkm'[lbl] for lbl in list(data.y.cpu().numpy() - 1)]

lc = LineCollection(X_embedded[out_dict['edges']],linewidth=0.05)
fig = plt.figure()
plt.gca().add_collection(lc)
plt.xlim(X_embedded[:,0].min(), X_embedded[:,0].max())
plt.ylim(X_embedded[:,1].min(), X_embedded[:,1].max())
plt.scatter(X_embedded[:,0],X_embedded[:,1], c=cols)

This gives the following plot:

While, I hope to somehow color each vertex in the following way:


回答1:


Here are two approaches.

The dots of regular scatter plots can have an interior color and an edge color. scatter accepts an array for either one of them, but not for both. So, you could just iterate through all edge colors and plot them in a loop over the same plot. Playing with linewidth might give help to visualize the true and the predicted colors together.

Matplotlib's plot function accepts marker filling styles, which have a possibility of being bicolored, either top-bottom or left-right. Per plot you can only give one type of style. So, for 5 colors, there are 25 combinations which can be drawn in a loop.

Bonus points:

While looping through the colors, plot can generate legend labels with the corresponding bicolored dot.

Here is some code to illustrate the concepts:

from matplotlib import pyplot as plt
from matplotlib.collections import LineCollection
import numpy as np

N = 50

labels = ['ant', 'bee', 'cat', 'dog', 'elk']  # suppose these are the labels for the prediction
colors = list('rgbkm') # a list of 5 colors
cols_true = np.repeat(range(5), N)  # suppose the first N have true color 0, the next N true color 1, ...
cols_pred = np.random.randint(0, 5, N * 5)  # as a demo, take a random number for each predicted color

# for x and y, suppose some 2D gaussian normal distribution around some centers,
#   this would make the 'true' colors nicely grouped 
x = np.concatenate([np.random.normal(cx, 2, N) for cx in [5, 9, 7, 2, 2]])
y = np.concatenate([np.random.normal(cy, 1.5, N) for cy in [2, 5, 9, 8, 3]])

fig, ax = plt.subplots(figsize=(10,6))
for tc in range(5):
    for pc in range(5):
        mask = (cols_true == tc) & (cols_pred == pc)
        plt.plot(x[mask], y[mask], c=colors[tc], markerfacecoloralt=colors[pc],
                 marker='.', linestyle='', markeredgecolor='None',
                 markersize=15, fillstyle='left', markeredgewidth=0,
                 label=f'Tr: {labels[tc]} - Pr: {labels[pc]}')
plt.legend(loc='upper right', bbox_to_anchor=(1, -0.1), fontsize=10, ncol=5)
plt.tight_layout()
plt.show()



来源:https://stackoverflow.com/questions/59810599/how-to-create-a-scatter-plot-with-two-colors-per-dot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!