How to arrange matplotlib scatters one over another by scale

I have 2 inputs (x,y) and 3 classes for that inputs which i mark by different colors. Using scaling I can see how many times does particular class is found at particular (x,y) point.

To show points on the chart i use such code:

ax.scatter(first_column, second_column, c=outputs_colors, s=labels_mean, alpha=0.3)


first_column - x_values; 
second_column - y_values; 
c=outputs_colors - colors for different classes; 
s=labels_mean - class share at a given point

When x,y inputs are various floats - the charts are informative: Plot Scatter Image 1

But when x,y are integers and there are many overlaps in classes the chart loses clarity: Plot Scatter Image 2

Is it possible to arrange scatters by size from bigger as background to smaller as foreground without using loop and separate plot.scatter for each class? To get something like this: Plot Scatter Image 3

Upvotes: 0

Views: 77

Answers (1)

Ruggero Turra
Ruggero Turra

Reputation: 17740

I guess you just need to order you data in such a way that larger markers are plotted first. I don't know how you store your data, so here a way that is data-oriented:

x = [1.5, 1.5, 1.5, 1.5, 1.5, 2.6, 2.6, 2.6, 2.6, 2.6]
y = np.array([1.5, 3.0, 7.4, 20., 20., 1.5, 3.0, 7.4, 20., 20.])
s = np.array([100, 100, 100, 50, 100, 100, 100, 100, 50, 100])
c = np.array(['k', 'k', 'k', 'r', 'k', 'k', 'k', 'k', 'r', 'k'])

if you just plot it as

from matplotlib import pyplot as plt
fig, ax = plt.subplots()
ax.scatter(x, y, s=s, c=c)

you will get your problem since the black markers are covering the smaller red ones. As far as I know there is no feature in matplotlib to address this problem, so you have to sort your points first by s in a reverse order.

import numpy as np
idx_sort = np.argsort(s)[::-1]
x, y, s, c = map(lambda vv: np.take(vv, idx_sort), [x, y, s, c])

Upvotes: 1

Related Questions