Search code examples
pythonmatplotlibscatter-plot

How to show the number of each label in scatter legend?


I want to make a legend that combined by two parts, first is the name of label, second is corresponding number of label, for example: 0:50; 1:50; 2:50

Now my code like that, I tired to add number of it by Counter function, however, it shows error: can only concatenate tuple (not "str") to tuple

import matplotlib.pyplot as plt
from sklearn import datasets
from collection import Counter
iris = datasets.load_iris()
X = iris.data
y = iris.target
df = pd.DataFrame(X, columns = iris.feature_names)

fig, ax = plt.subplots(figsize=(12,8))
points = ax.scatter(df.values[:,0], 
    df.values[:,1],
    c = y)
legend1 = ax.legend(*points.legend_elements() +':' + list(Counter(y).values()), loc = "lower left",title = 'clusters')  
#ax.add_artist(legend1)
#handles, labels = points.legend_elements(prop = 'sizes')
#legend2 = ax.legend(handles, labels, loc='upper right')
plt.show()

Solution

  • Since the elements of the legend are retrieved, we will process the retrieved label and concatenate the values in a string. You can then use that as the legend.

    import matplotlib.pyplot as plt
    from sklearn import datasets
    from collections import Counter
    import pandas as pd
    
    iris = datasets.load_iris()
    X = iris.data
    y = iris.target
    df = pd.DataFrame(X, columns = iris.feature_names)
    
    fig, ax = plt.subplots(figsize=(12,8))
    points = ax.scatter(df.values[:,0], 
        df.values[:,1],
        c = y)
    # create labels and handles
    labels = ['{}:{}'.format(l,t) for l,t in zip(points.legend_elements()[1], list(Counter(y).values()))]
    handles = [points.legend_elements()[0][0],points.legend_elements()[0][1],points.legend_elements()[0][2]]
    legend1 = ax.legend(handles, [labels[0],labels[1],labels[2]], loc = "lower left",title = 'clusters')  
    
    plt.show()
    

    enter image description here