Search code examples
pythonpandasmatplotliblegendscatter

Why scatter.legend_elements is limited in size?


I'm trying to plot with this code :

import pandas as pd
import random as rd
import matplotlib.pyplot as plt

datasets = ['a', 'a', 'b', 'b', 'b', 'c', 'd', 'd', 'e', 'f', 'g','g','g','h', 'i', 'j', 'k', 'k','l','m','n','o','p','q','r','s','t','u','v']
d = {'x': [rd.random()*len(i) for i in datasets]
     , 'y': [rd.random()*len(i) for i in datasets]
     , 'source': datasets} 
df = pd.DataFrame(data=d)
fig = plt.figure()
categ = df.source.astype('category')
datasets_legend = dict(enumerate(categ.cat.categories)).values()
ax = fig.add_subplot(111)
scatter = ax.scatter(df.x, df.y, c=categ.cat.codes, cmap='Set3')
plt.title("test", fontsize=18)
plt.legend(handles=scatter.legend_elements()[0], labels=datasets_legend, title="datasets")
plt.show()

But the legend is not showing every line (it is limited to the 9th first elements). Any idea how can I get the full legend ?

Best regards


Solution

  • From the docs, you can see there is a num option to scatter.legend_elements() which controls how many elements should be included in the legend. By default, num='auto', which tries to find a nice number of elements to display.

    To show all elements, you can use num=None, which should give you labels for all the unique elements in the mappable.

    So, use this line of code:

    plt.legend(handles=scatter.legend_elements(num=None)[0], labels=datasets_legend, title="datasets")
    

    Which produces this figure:

    enter image description here

    Docs for the num parameter, for reference:

    num int, None, "auto" (default), array-like, or Locator

    Target number of elements to create. If None, use all unique elements of the mappable array. If an integer, target to use num elements in the normed range. If "auto", try to determine which option better suits the nature of the data. The number of created elements may slightly deviate from num due to a Locator being used to find useful locations. If a list or array, use exactly those elements for the legend. Finally, a Locator can be provided.