Matplotlib,散布着三个图例

Posted

技术标签:

【中文标题】Matplotlib,散布着三个图例【英文标题】:Matplotlib, scatter with three legends 【发布时间】:2020-06-16 23:12:04 【问题描述】:

我正在研究 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】:

我找到了解决办法!

我通过在绘图初始化之后(嵌套 for 之前)移动假散点图解决了这个问题。我绘制了第一个假散点图,定义了它的图例,然后清除轴 plt.cla()。我重复第二个假散点图。现在,我绘制主散点图(嵌套的 for),并使用 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()

【讨论】:

以上是关于Matplotlib,散布着三个图例的主要内容,如果未能解决你的问题,请参考以下文章

Matplotlib - 全局图例和标题旁边的子图

Python-Matplotlib 14 图例legend

Python_matplotlib画图时图例说明(legend)放到图像外侧

matplotlib.pyplot 导引

matplot:在matplotlib中显示标签的问题[重复]

4.11Python数据处理篇之Matplotlib系列---图例,网格,背景的设置