关于python:在图例MATPLOTLIB前面绘制箭头

 2021-04-26 

Plotting arrow in front of legend MATPLOTLIB

我对Python完全陌生,我正在尝试为我的学士学位论文做图。此图包括必须出现在图例中的箭头。我在Stackoverflow上看到了一些问题,如何在图例中添加箭头,但无法跟随它们。因此,我用线宽为零的线条作为占位符,并想在图例前面生成一个箭头。不幸的是,我无法将箭头放在图例的前面。您可以在倒数第二行的代码行中看到我的箭头。我尝试将其与" zorder "一起移到前面,但是它不起作用。正如您在链接的图形中看到的那样,只有通过透明的图例才能看到它。我很乐意为您提供帮助,让您在图例中找到这个箭头。预先谢谢您!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import matplotlib
matplotlib.rcParams['text.usetex'] = True
import numpy as np
import scipy.io as sio

plt.style.use('ggplot')

mat=sio.loadmat('MatlabDaten/absolut.mat')
x=mat['x']
x=x[0]
xaufp=mat['xaufp']
xaufp=xaufp[0]
y=mat['y']
y=y[0]
yaufp=mat['yaufp']
yaufp=yaufp[0]
pfeillaenge=mat['pfeillaenge']
pfeillaenge=pfeillaenge[0]
pfeilpos=mat['pfeilpos']

ppfad=plt.plot(x,y,'C0',label='Geplanter Pfad')
paufp=plt.plot(xaufp,yaufp,'C0o',label='Aufpunkte')
plt.plot(0,0,lw=0,label='Lokale Orientierung')
for count in pfeilpos:
    ppfeil=plt.arrow(count[0],count[1],pfeillaenge[0],pfeillaenge[1], fc='C1', ec='C1', lw = 0.5, head_width=0.05, head_length=0.06, overhang = 0.3, length_includes_head= True, clip_on = False, label='Lokale Orientierung')
plt.xlim(0,5)
plt.ylim(-1.5,1.5)
plt.xlabel('$x$-Koordinate')
plt.ylabel('$y$-Koordinate')
plt.title('Absolute Orientierung')
plt.legend(handles=[ppfad,paufp,ppfeil],loc='lower left')
pfeil=plt.arrow(0.15,-1.32,0.3,0, fc='C1', ec='C1', lw = 0.5, head_width=0.05, head_length=0.06, overhang = 0.3, length_includes_head= True, clip_on = False, label='Lokale Orientierung')
pfeil.set_zorder(+5)

结果图:
Resulting


处理此问题的正确方法是创建一个自定义图例处理程序。以下内容基于matplotlib的图例指南

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import matplotlib
matplotlib.rcParams['text.usetex'] = True
import numpy as np
import scipy.io as sio
from matplotlib.legend_handler import HandlerPatch
import matplotlib.patches as mpatches

class HandlerArrow(HandlerPatch):
    def create_artists(self, legend, orig_handle,
                       xdescent, ydescent, width, height, fontsize, trans):
        p = mpatches.FancyArrow(0, 0.5*height, width, 0, length_includes_head=True, head_width=0.75*height )
        self.update_prop(p, orig_handle, legend)
        p.set_transform(trans)
        return [p]


plt.style.use('ggplot')

#mat=sio.loadmat('MatlabDaten/absolut.mat')
#x=mat['x']
#x=x[0]
#xaufp=mat['xaufp']
#xaufp=xaufp[0]
#y=mat['y']
#y=y[0]
#yaufp=mat['yaufp']
#yaufp=yaufp[0]
#pfeillaenge=mat['pfeillaenge']
#pfeillaenge=pfeillaenge[0]
#pfeilpos=mat['pfeilpos']
x = [1,4]
y = [-1,1]
xaufp = [1,4]
yaufp = [-1,1]
pfeilpos = [[1,-1],[4,1]]
pfeillaenge = [0,0.25]

fig = plt.figure()
ppfad=plt.plot(x,y,'C0',label='Geplanter Pfad')
paufp=plt.plot(xaufp,yaufp,'C0o',label='Aufpunkte')
for count in pfeilpos:
    ppfeil=plt.arrow(count[0],count[1],pfeillaenge[0],pfeillaenge[1], fc='C1', ec='C1', lw = 0.5, head_width=0.05, head_length=0.06, overhang = 0.3, length_includes_head= True, clip_on = False, label='Lokale Orientierung')
plt.xlim(0,5)
plt.ylim(-1.5,1.5)
plt.xlabel('$x$-Koordinate')
plt.ylabel('$y$-Koordinate')
plt.title('Absolute Orientierung')

h,l = plt.gca().get_legend_handles_labels()
h.append(ppfeil)
l.append('Lokale Orientierung')
plt.legend(h,l, handler_map={mpatches.FancyArrow : HandlerArrow()})

enter

请注意,这通常是矫kill过正,并且您还可以使用scatter的功能来使用自定义标记来欺骗matplotlib:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import matplotlib
matplotlib.rcParams['text.usetex'] = True
import numpy as np
import scipy.io as sio

plt.style.use('ggplot')

#mat=sio.loadmat('MatlabDaten/absolut.mat')
#x=mat['x']
#x=x[0]
#xaufp=mat['xaufp']
#xaufp=xaufp[0]
#y=mat['y']
#y=y[0]
#yaufp=mat['yaufp']
#yaufp=yaufp[0]
#pfeillaenge=mat['pfeillaenge']
#pfeillaenge=pfeillaenge[0]
#pfeilpos=mat['pfeilpos']
x = [1,4]
y = [-1,1]
xaufp = [1,4]
yaufp = [-1,1]
pfeilpos = [[1,-1],[4,1]]
pfeillaenge = [0,0.25]

fig = plt.figure()
ppfad=plt.plot(x,y,'C0',label='Geplanter Pfad')
paufp=plt.plot(xaufp,yaufp,'C0o',label='Aufpunkte')
for count in pfeilpos:
    ppfeil=plt.arrow(count[0],count[1],pfeillaenge[0],pfeillaenge[1], fc='C1', ec='C1', lw = 0.5, head_width=0.05, head_length=0.06, overhang = 0.3, length_includes_head= True, clip_on = False, label='Lokale Orientierung')
plt.scatter([],[],marker=r'$\
ightarrow$'
, label='Lokale Orientierung', color='C1', s=100) # dummy scatter to add an item to the legend
plt.xlim(0,5)
plt.ylim(-1.5,1.5)
plt.xlabel('$x$-Koordinate')
plt.ylabel('$y$-Koordinate')
plt.title('Absolute Orientierung')

plt.legend()

enter