Legende drehen oder Patch zur Achsenbeschriftung in matplotlib hinzufügen

Ich habe einen ungewöhnlichen Anwendungsfall in matplotlib, den ich zu lösen versuche. Ich habe ein Achsenpaar mit @ ersteltwinx(). Jedes enthält genau ein Linienobjekt mit unterschiedlichen Stilen. Anstatt eine konventionelle Legende zu haben, muss ich dem y-Label jeder Achse einen Patch hinzufügen, der jede Linie darstellt. Folgendes versuche ich zu erreichen:

Idealerweise würde sich der Patch über dem Text befinden, aber das ist ein sehr kleines Detail im Vergleich zum Erreichen des gewünschten Ergebnisses.

ch habe zwei Lösungsansätze für dieses Problem ausprobiert, die beide fehlgeschlagen sind. Vielleicht kann ein Matplotlib-Guru helfen:

# 1: Verschobene Legenden verwenden

from matplotlib import pyplot as plt
fig = plt.figure()
ax = fig.subplots(111)
ax = fig.add_subplot(111)
ax2 = ax.twinx()
l1, = ax.plot((0, 1), (1, 0), linestyle='-', color='blue')
l2, = ax.plot((0, 1), (0, 1), linestyle='--', color='red')
leg1 = ax.legend([l1], ['Solid Blue Line'], bbox_to_anchor=(-0.102, 0., 0.102, 1.), frameon=False, mode='expand', loc=4)
leg2 = ax2.legend([l2], ['Dashed Red Line'], bbox_to_anchor=(1.102, 0., 0.102, 1.), frameon=False, mode='expand', loc=3)

Wie erwartet werden die Legenden hierdurch korrekt platziert, aber nicht gedreht. Ich kann die Rotation nicht durchführen, weil anscheinend Legenden nicht gedreht werden können, obwohl sie @ sinArtist Erweiterungen. Z.B.,leg1.set_transform(leg1.get_transform() + Affine2D().rotate_deg(-90)) ändert nichts am Winkel der Legende:

# 2 Verwenden einer benutzerdefinierten AnchoredOffsetBox

ei diesem Ansatz habe ich versucht, ein benutzerdefiniertes Feld zu erstellen, das einen Text und einen Patch enthält. Leider wird der Patch nicht richtig angezeigt.

from matplotlib import pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, DrawingArea, HPacker
from matplotlib.transform import Affine2D

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1, 2, 3], [0, 3, -1], color='g', linestyle='solid')
textArea = TextArea('This is an x-label')
drawArea = DrawingArea(1., 1.)
patch = Line2D((0, 1), (0, 1), color='g', linestyle='solid')
drawArea.add_artist(patch)
content = HPacker(children=[textArea, drawArea], align="center", pad=0, sep=5)
label = AnchoredOffsetbox(loc=10, child=content, pad=0, bbox_to_anchor=(0.5, -0.1), bbox_transform=ax.transAxes, frameon=False)
ax.add_artist(label)
label.set_transform(label.get_transform() + Affine2D().rotate_deg(-90))

Again, die Rotation funktioniert überhaupt nicht. Außerdem ist der Patch nicht so angemessen skaliert wie in einem Legendeneintrag (beachten Sie den kleinen grünen Punkt am Ende des Etiketts):

Ist es möglich, so etwas wie das gewünschte Ergebnis in MatPlotLib zu erzielen? Ich bin bereit, in den Quellcode einzutauchen und möglicherweise eine PR einzureichen, wenn es hilft, aber ich habe keine klare Vorstellung davon, wo ich anfangen soll.

AKTUALISIERE

Beim Betrachten des Quellcodes wird dasset_transform Methoden vonmatplotlib.offsetbox.TextArea undmatplotlib.offsetbox.DrawingArea werden komplett ignoriert. Dies bedeutet, dass mein zweiter Versuch sinnlos wäre, selbst wenn ich den Patch zum korrekten Zeichnen bringen würde.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage