9 votes

Légende avec ligne verticale dans matplotlib

J'ai besoin d'afficher une ligne verticale dans une légende matplotlib pour une raison spécifique. J'essaie de faire comprendre à matplotlib que je veux une ligne verticale avec la fonction lines.Line2D(x,y) mais cela ne fonctionne manifestement pas.

import matplotlib.pyplot as plt
from matplotlib import lines
fig, ax = plt.subplots()
ax.plot([0,0],[0,3])
lgd = []
lgd.append(lines.Line2D([0,0],[0,1], color = 'blue', label = 'Vertical line'))
plt.legend(handles = lgd)

enter image description here

J'ai besoin que la ligne apparaisse à la verticale, pas la légende. Quelqu'un peut-il m'aider ?

8voto

DavidG Points 10145

Vous pouvez utiliser le marqueur de ligne verticale lorsque vous créez votre objet line2D. Vous trouverez une liste de marqueurs valides aquí .

import matplotlib.pyplot as plt
from matplotlib import lines

fig, ax = plt.subplots()
ax.plot([0,0],[0,3])

vertical_line = lines.Line2D([], [], color='#1f77b4', marker='|', linestyle='None',
                          markersize=10, markeredgewidth=1.5, label='Vertical line')

plt.legend(handles = [vertical_line])

plt.show()

enter image description here

4voto

Marquez toutes les lignes verticalement

Si l'objectif est de faire en sorte que chaque ligne soit marquée verticalement plutôt qu'horizontalement dans la légende, vous pouvez mettre à jour le gestionnaire de la légende via la commande handler_map .

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D

plt.plot([1,3,2], label='something')
plt.plot([.5,.5], [1,3], label='something else')

def update_prop(handle, orig):
    handle.update_from(orig)
    x,y = handle.get_data()
    handle.set_data([np.mean(x)]*2, [0, 2*y[0]])

plt.legend(handler_map={plt.Line2D:HandlerLine2D(update_func=update_prop)})

plt.show()

enter image description here

Reproduire la ligne en miniature

Si l'objectif est d'obtenir une version miniature de la ligne tracée dans la légende, vous pouvez en principe utiliser cette réponse pour Utilisation d'une version miniature des données tracées comme poignée de légende . Une légère modification est cependant nécessaire pour tenir compte d'une boîte de délimitation dont la largeur peut être nulle, que j'ai également modifiée dans la réponse originale. Ici, cela ressemblerait à :

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D
import matplotlib.path as mpath
from matplotlib.transforms import BboxTransformFrom, BboxTransformTo, Bbox

class HandlerMiniatureLine(HandlerLine2D):
    def create_artists(self, legend, orig_handle,
                       xdescent, ydescent, width, height, fontsize,
                       trans):

        legline, _ = HandlerLine2D.create_artists(self,legend, orig_handle,
                                xdescent, ydescent, width, height, fontsize, trans)

        legline.set_data(*orig_handle.get_data())

        ext = mpath.get_paths_extents([orig_handle.get_path()])
        if ext.width == 0:
            ext.x0 -= 0.1
            ext.x1 += 0.1
        bbox0 = BboxTransformFrom(ext)
        bbox1 = BboxTransformTo(Bbox.from_bounds(xdescent, ydescent, width, height))

        legline.set_transform(bbox0 + bbox1 + trans)
        return legline,

plt.plot([1,3,2], label='something')
plt.plot([.5,.5], [1,3], label='something else')

plt.legend(handler_map={plt.Line2D:HandlerMiniatureLine()})

plt.show()

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X