неполная легенда точечной диаграммы: недостаточно размеров для текущих точек

#python #matplotlib #plot #legend #scatter

#python #matplotlib #график #легенда #разброс

Вопрос:

Я хочу иметь в легенде все размеры, присутствующие на графике. Я не знаю, почему я печатаю только 1 размер и только 1 цену. Это код:

 import numpy as np
import matplotlib.pyplot as plt

# canvas , blackboard learn, moodle, D2L, Edmodo
# green  ,    blue         ,yellow , red, orange

# x= CVSS v2 score (variabile 1)
x=[0.22,-1.4,-0.86,0.65,0.84]

# y= supported OS (variabile 2)
y=[1.16,-0.77,-1.25,0.68,0.19]

colors=['green','blue','black','red','orange']
labels=['Canvas','BlackBoard Learn','Moodle','D2L', 'Edmodo']
scale=[1.76,24,1.7,1.83,8.75]  

fig, ax = plt.subplots(figsize=(7,5))

for i in range(0,5):
    scale[i]*=200
    scatter=ax.scatter(x[i], y[i], s=scale[i], c=colors[i], label=labels[i], alpha=0.45)

    
lgnd= plt.legend(loc="upper right")
plt.xlabel('CVSS v2 score')
plt.ylabel('supported OS')
plt.ylim((-2,2))
plt.xlim((-1.5,4))

lgnd.legendHandles[0]._sizes = [60]
lgnd.legendHandles[1]._sizes = [60]
lgnd.legendHandles[2]._sizes = [60]
lgnd.legendHandles[3]._sizes = [60]
lgnd.legendHandles[4]._sizes = [60]
ax.add_artist(lgnd)

kw = dict(prop="sizes", num=20, color=scatter.cmap(0.1), fmt="$ {x:.2f}" " / month", func=lambda s: s/200)
legend2 = ax.legend(*scatter.legend_elements(**kw), prop={'size':14}, loc="lower right", title="Price") 
plt.show()
 

Это вывод:

введите описание изображения здесь

Я бы хотел иметь что-то вроде этого:

введите описание изображения здесь

Ответ №1:

Это можно сделать, создав виртуальных художников без точек данных в качестве пользовательских дескрипторов легенды, в которых вы можете указать, как вы хотите, чтобы ваша легенда выглядела.

Кроме того, если вы используете объектно-ориентированный подход в matplotlib, вы должны быть последовательными, а также устанавливать ограничения и метки осей, используя объектно-ориентированный подход, вызывая вместо этого соответствующие методы оси (если сделали это в коде для вас).

 import numpy as np
import matplotlib.pyplot as plt

# x= CVSS v2 score (variabile 1)
x=[0.22,-1.4,-0.86,0.65,0.84]

# y= supported OS (variabile 2)
y=[1.16,-0.77,-1.25,0.68,0.19]

colors = ['green','blue','black','red','orange']
labels = ['Canvas','BlackBoard Learn','Moodle','D2L', 'Edmodo']
prices = [1.76,24,1.7,1.83,8.75]
scales = [price * 200 for price in prices]

fig, ax = plt.subplots(figsize=(7,5))

ax.set_xlabel('CVSS v2 score')
ax.set_ylabel('supported OS')
ax.set_ylim((-2,2))
ax.set_xlim((-1.5,4))

for i in range(0,5):
    scatter=ax.scatter(x[i], y[i], s=scales[i], c=colors[i], label=labels[i], alpha=0.45)

labels1 = labels
handles1 = [ax.scatter([], [], s=60, c=color, alpha=0.45) for color in colors]
legend1 = ax.legend(handles=handles1, labels=labels1, loc="upper right")

labels2 = [f'$ {price} / month' for price in sorted(prices)]
handles2 = [ax.scatter([], [], s=size, c='purple', alpha=0.45) for size in sorted(scales)]
legend2 = ax.legend(handles=handles2, labels=labels2, loc="lower right")
ax.add_artist(legend1)

plt.show()
 

Мой результат выглядит так:

введите описание изображения здесь