Матплотлиб, скаттер с тремя легендами - PullRequest
0 голосов
/ 04 марта 2020

Я работаю над графиком рассеяния Matplotlib и пытаюсь добавить три легенды, основанные на цвете, форме и размере маркеров. Первые две легенды, цвет и форма, были успешно добавлены к сюжету, в то время как легенда размера как-то связана с легендой формы. Есть ли способ сделать третью легенду правильной?

import numpy as np
import matplotlib.pyplot as plt
import os
from matplotlib.legend import Legend

# Plotting parameters
colors = ['#0060ad','#ffdc6b','#37a7e8','#d8141c','#32cf3a','#a1a1a1','#f700ff','#ffb6c1','#a1a1a1','#fff200']
markers = ['o','s','v','^','P','*']

param1 = range(10,15,1)
param1_len = len(param1)
param1_name = 'Parameter 1'
param1_unit = ''

param2 = range(88,133,22)
param2_len = len(param2)
param2_name = 'Parameter 2'
param2_unit = ' [unit]'

param3 = ["1", "2"]
param3_len = len(param3)
param3_name = "Parameter 3"
param3_unit = ""

area_fix = 100
area_var = np.zeros((param1_len,1))
for i in range(param1_len):
    area_var[i,0] = 50*(2**i)

k = 1

Var_1 = [0.244, 0.294, 0.333, 0.364, 0.389, 0.286, 0.332, 0.365, 0.391, 0.411, 0.316, 0.355, 0.384, 0.406, 0.423, 0.324, 0.364, 0.391, 0.413, 0.429, 0.349, 0.383, 0.407, 0.426, 0.440, 0.366, 0.395, 0.417, 0.433, 0.446]
Var_2 = [0.552, 0.579, 0.600, 0.617, 0.631, 0.613, 0.641, 0.662, 0.680, 0.693, 0.669, 0.698, 0.719, 0.736, 0.749, 0.658, 0.687, 0.708, 0.725, 0.737, 0.736, 0.767, 0.790, 0.807, 0.821, 0.805, 0.835, 0.858, 0.875, 0.890]

# -------------------------------------------------------------------------------------------------------------------

## Plots
plt.figure(k)
f, ax = plt.subplots(1, sharey = True, figsize = (10, 8))
n = 0

for n in range(param3_len): #3-parameter scatter: color, size and shape
    i = 0
    for j in range(param2_len):
        sc = ax.scatter((Var_1[((param1_len*param2_len)*n + param1_len*i) : ((param1_len*param2_len)*n + param1_len*(i+1))])*100,
                (Var_2[((param1_len*param2_len)*n + param1_len*i) : ((param1_len*param2_len)*n + param1_len*(i+1))])*100,   
                s = area_var,               
                alpha = 0.6,
                c = colors[i],
                edgecolor = colors[i],
                marker = markers[n]) 
        i = i +1

leg2 = ax.legend(labels = param2,
         bbox_to_anchor = (0.5, -0.3),
         loc = 'lower center',
         ncol = param2_len,
         fontsize = 12,
         scatterpoints = 1, 
         frameon = False, 
         labelspacing = 1, 
         title = param2_name + ' ' + param2_unit, 
         framealpha = 0)
plt.setp(leg2.get_title(), fontsize = 13)

for h in leg2.legendHandles:
    h._sizes = [area_fix]

ax.grid(b = True, which = 'major', color = 'grey', linestyle = ':')
ax.set_xlabel('Variable 1 [unit]')
ax.set_ylabel('Variable 2 [unit]')

hand3 = []
for i in range(param3_len):
    fakescatter3 = ax.scatter([], [], c = 'black', alpha = 0.2, s = area_fix, label = param3[i], marker = markers[i])
    hand3.append([fakescatter3])
leg3 = ax.legend(handles = hand3,
         labels = param3,
         scatterpoints = 1,
         ncol = 1, 
         frameon = False, 
         labelspacing = 1, 
         title = param3_name + ' ' + param3_unit, 
         framealpha = 0,
         fontsize = 12,
         loc = 'upper left')
if param3_len > 0:
    plt.setp(leg3.get_title(), fontsize = 13)
ax.add_artist(leg2)

hand1 = []
for j in range(param1_len):
    fakescatter1 = ax.scatter([], [], c = 'black', alpha = 0.2, s = area_var[j], label = param1[j], marker = markers[0])
    hand1.append([fakescatter1])

leg1 = ax.legend(handles = hand1,
         labels = param1,
         scatterpoints = 1,
         ncol = 1, 
         frameon = False, 
         labelspacing = 2, 
         title = param1_name + ' ' + param1_unit, 
         framealpha = 0,
         fontsize = 12,
         loc = 'best')
plt.setp(leg1.get_title(), fontsize = 13)

ax.add_artist(leg3)

plt.tight_layout()
f.subplots_adjust(top = 0.95, bottom = 0.24)
title = 'Variable 1 vs. Variable 2'
plt.suptitle(title, fontsize = 14)
plt.show()

Заранее спасибо!

1 Ответ

0 голосов
/ 06 марта 2020

Я нашел решение!

Я решил проблему, переместив фиктивный график рассеяния сразу после инициализации графика (перед вложенным для). Я строю первый поддельный разброс, определяю его легенду и затем очищаю оси plt.cla (). Я повторяю для второго поддельного скаттера. Теперь я строю основной разброс (вложенный для) и добавляю легенды из поддельных разбросов с помощью ax.add_artist (leg3), ax.add_artist (leg2)

plt.figure(k)
f, ax = plt.subplots(1, sharey = True, figsize = (10, 8))
n = 0

hand3 = []
for i in range(param3_len):
    fakescatter3 = ax.scatter([], [], c = 'black', alpha = 0.2, s = area_fix, label = param3[i], marker = markers[i])
    hand3.append([fakescatter3])
leg3 = ax.legend(handles = hand3,
         labels = param3,
         scatterpoints = 1,
         ncol = 1, 
         frameon = False, 
         labelspacing = 1, 
         title = param3_name + ' ' + param3_unit, 
         framealpha = 0,
         fontsize = 12,
         loc = 'upper left')
if param3_len > 0:
    plt.setp(leg3.get_title(), fontsize = 13)

plt.cla()

hand1 = []
for j in range(param1_len):
    fakescatter1 = ax.scatter([], [], c = 'black', alpha = 0.2, s = area_var[j], label = param1[j], marker = markers[0])
    hand1.append([fakescatter1])

leg1 = ax.legend(handles = hand1,
         labels = param1,
         scatterpoints = 1,
         ncol = 1, 
         frameon = False, 
         labelspacing = 2, 
         title = param1_name + ' ' + param1_unit, 
         framealpha = 0,
         fontsize = 12,
         loc = 'best')
plt.setp(leg1.get_title(), fontsize = 13)

plt.cla()

for n in range(param3_len): #3-parameter scatter: color, size and shape
    i = 0
    for j in range(param2_len):
        sc = ax.scatter((Var_1[((param1_len*param2_len)*n + param1_len*i) : ((param1_len*param2_len)*n + param1_len*(i+1))])*100,
                (Var_2[((param1_len*param2_len)*n + param1_len*i) : ((param1_len*param2_len)*n + param1_len*(i+1))])*100,   
                s = area_var,               
                alpha = 0.6,
                c = colors[i],
                edgecolor = colors[i],
                marker = markers[n]) 
        i = i +1

leg2 = ax.legend(labels = param2,
         bbox_to_anchor = (0.5, -0.3),
         loc = 'lower center',
         ncol = param2_len,
         fontsize = 12,
         scatterpoints = 1, 
         frameon = False, 
         labelspacing = 1, 
         title = param2_name + ' ' + param2_unit, 
         framealpha = 0)
plt.setp(leg2.get_title(), fontsize = 13)

for h in leg2.legendHandles:
    h._sizes = [area_fix]

ax.grid(b = True, which = 'major', color = 'grey', linestyle = ':')
ax.set_xlabel('Variable 1 [unit]')
ax.set_ylabel('Variable 2 [unit]')

ax.add_artist(leg2)
ax.add_artist(leg3)

plt.tight_layout()
f.subplots_adjust(top = 0.95, bottom = 0.24)
title = 'Variable 1 vs. Variable 2'
plt.suptitle(title, fontsize = 14)
plt.show()
...