В настоящее время я создаю диаграмму рассеяния с результатами некоторой оценки, которую я провожу.
Чтобы получить фрейм данных той же структуры, что и у меня, вы можете запустить:
import pandas as pd
models = ["60000_25_6", "60000_26_6"]
results = []
for i in range(10):
for model in models:
results.append({"simulation": i, "model_id": model, "count_at_1": 1, "count_at_5": 5, "count_at_10": 10})
df = pd.DataFrame(results)
В итоге вы получите фрейм данных pandas, который выглядит следующим образом, только со значениями по умолчанию (это фрейм данных меньшего размера, обратите внимание, что размер является переменным и намного больше в зависимости от используемых мной настроек):
simulation model_id count_at_1 count_at_5 count_at_10
0 0 60000_25_6 60 77 84
1 0 60000_26_6 60 76 83
2 1 60000_25_6 69 80 82
...
18 9 60000_25_6 1 70 79
19 9 60000_26_6 1 68 74
Затем я использую следующий код, чтобы добавить цвета к каждой точке:
import matplotlib.pyplot as plt
colors = plt.get_cmap('hsv')
colors = [colors(i) for i in np.linspace(0,0.95, len(models))]
cmap = {model: colors[i] for i, model in enumerate(models)}
df['color'] = df.apply(lambda row: cmap[row['model_id']], axis=1)
И df теперь:
simulation model_id count_at_1 count_at_5 count_at_10 color
0 0 60000_25_6 74 81 83 (1.0, 0.0, 0.0, 1.0)
1 0 60000_26_6 75 80 83 (1.0, 0.0, 0.5, 1.0)
2 1 60000_25_6 71 84 89 (1.0, 0.0, 0.0, 1.0)
...
18 9 60000_25_6 2 69 79 (1.0, 0.0, 0.0, 1.0)
19 9 60000_26_6 2 72 78 (1.0, 0.0, 0.5, 1.0)
Однако когда я бегу:
df.plot.scatter('count_at_1', 'count_at_5', c='color', legend=True)
plt.show()
Никакой легенды не появляется, я просто получаю обычный сюжет, например:
Как я могу добавить легенду, которая будет выглядеть примерно так:
[model_id] [color]
...
Но в обычном формате matplotlib я возьму его в любое место сюжета.
Данным необходимо присвоить label
легенду, поэтому один из вариантов:
fig, ax = plt.subplots()
for model in df['model_id'].unique():
df[df["model_id"].eq(model)].plot.scatter('count_at_1', 'count_at_5',
c='color', label=model,
ax=ax)
ax.legend(markerfirst=False)
С вашим примером данных:
Это отлично работает для меня! Я хотел продолжать использовать df.plot, но не думаю, что это возможно без хакерских вещей, и это нежелательно.
Добавление этого сработало для меня
from matplotlib.patches import Patch
ax = df.plot.scatter(......)
ax.legend(handles=[Patch(color=cmap[model], label=model) for model in models])
По умолчанию legend()
пытается использовать связанный ярлык, который вы использовали при звонке scatter()
(источник ). В вашем случае, поскольку вы не указываете метки, вы можете передавать патчи так, как это сделал я ( источник)
Это решение может иметь смысл, если вам нужно создать диаграмму рассеяния за один раз, не указывая отдельные метки, как вы это сделали.
Да, это выглядит намного чище (добавление меток при создании графиков) вместо того, чтобы делать какие-то хакерские действия, чтобы добавить их позже.