Que signifie un argument tuple à 4 éléments pour "bbox to anchor" dans matplotlib?

dans la section " emplacement de la légende " du" Guide des légendes "sur le site matplotlib, il y a un petit script où la ligne 9 est plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=2, mode="expand", borderaxespad=0.) . Tous les tuples que j'ai vus passés à bbox_to_anchor ont 2 éléments dedans, mais celui-ci en a 4. Que signifie Chaque élément si le tuple passé a 4 éléments?



Je l'ai regardé dans le pyplot.legend "docs , et il a dit quelque chose sur Coordonnées bbox_transform . Alors j'ai regardé autour et j'ai trouvé matplotlib.transforms.Bbox avec un static from_bounds(x0, y0, width, height) .



Je suppose que la configuration pour le paramètre 4-tuple était basée sur ce from_bounds . J'ai copié le script vers Spyder, j'ai fait %matplotlib dans une console Ipython, et j'ai changé quelques valeurs. Cela semblait logique, mais quand j'ai essayé de changer .102 en quelque chose comme 0.9 , la légende n'a pas changé. Je pense que le tuple est basé sur from_bounds , Je ne sais pas pourquoi changer la dernière valeur du tuple n'a rien fait.

18
demandé sur DragonautX 2016-10-01 08:36:24

2 réponses

vous avez raison, le 4-tuple dans plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3) est défini comme (x0, y0, width, height)(x0,y0) sont les coordonnées du coin inférieur gauche de la boîte limite.

alors que ces paramètres établissent la boîte limite pour la légende, la taille verticale réelle de la légende est réduite à la taille qui est nécessaire pour mettre les éléments. De plus, sa position n'est déterminée qu'en conjonction avec le paramètre loc . Le paramètre loc définit l'alignement de la légende à l'intérieur du bounding box, de sorte que dans certains cas, aucune différence ne sera vu lors de la modification du height , comparer par exemple graphe (2) et (4).

enter image description here

21
répondu ImportanceOfBeingErnest 2016-10-01 11:40:28

@ImportanceOfBeingErnest la réponse est excellente. Je voudrais développer sur la signification de alignment entre la boîte de légende et la boîte de limite. Cela signifie que la position différente indiquée par le paramètre loc pour la boîte de légende et la boîte de limite sera placée au même point.

par exemple, si loc='center' , le centre de la boîte de légende et la boîte limite seront au même point. Si loc='center right' , le centre droit de la boîte de légende et le boîte englobante sera au même point. Désolé pour le niveau de verbosité...

prenons un exemple concret pour illustrer cette idée,

quatre coordonnées pour bbox_to_anchor

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as patches

locs = ['upper right', 'lower left', 'center left', 'lower center', 'center',
        'right']

x0, y0, width, height = 0.5, 0.5, 0.1, 0.4

x = np.arange(0.1, 4, 0.1)
y = 1.0/x

fig = plt.figure(figsize=(10, 10))

idx = 1
for i in range(0, 2):
    for j in range(0, 3):
        ax = fig.add_subplot(3, 2, idx)
        ax.plot(x, y, label=r'$\frac{1}{x}$')
        ax.legend(loc=locs[idx-1], bbox_to_anchor=(x0, y0, width, height),
            edgecolor='g', fontsize='large', framealpha=0.5,
            borderaxespad=0)
        ax.add_patch(
            patches.Rectangle((x0, y0), width, height, color='r',
                            fill=False, transform=ax.transAxes)
        )
        ax.text(0.6, 0.2, s="loc = '{}'".format(locs[idx-1]),
        transform=ax.transAxes)
        idx += 1

plt.show()

Le code ci-dessus produit l'image ci-dessous, enter image description here

Dans l'image, la zone rouge est la boîte englobante, et la boîte verte est la boîte de la légende. loc dans chaque sous-placette indique la relation d'alignement entre les deux cases.

deux coordonnées pour bbox_to_anchor

Lorsqu'il n'y a que deux valeurs données à bbox_to_anchor , la largeur et la hauteur de la zone limite sont réglées à zéro. Modifions légèrement le code ci-dessus,

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as patches

locs = ['upper right', 'lower left', 'center left', 'lower center', 'center',
        'right']

x0, y0, width, height = 0.5, 0.5, 0, 0

x = np.arange(0.1, 4, 0.1)
y = 1.0/x

fig = plt.figure(figsize=(10, 10))

idx = 1
for i in range(0, 2):
    for j in range(0, 3):
        ax = fig.add_subplot(3, 2, idx)
        ax.plot(x, y, label=r'$\frac{1}{x}$')
        ax.legend(loc=locs[idx-1], bbox_to_anchor=(x0, y0, width, height),
            edgecolor='g', fontsize='large', framealpha=0.5,
            borderaxespad=0)
        ax.add_patch(
            patches.Rectangle((x0, y0), width, height, color='r',
                            fill=False, transform=ax.transAxes)
        )
        ax.text(0.6, 0.2, s="loc = '{}'".format(locs[idx-1]),
        transform=ax.transAxes)
        ax.plot(x0, y0, 'r.', markersize=8, transform=ax.transAxes)
        idx += 1

plt.show()

maintenant, l'image produit devient

enter image description here

Rouge le point dans l'image ci-dessus indique la position de la coordonnée de la boîte liée.

6
répondu jdhao 2018-04-17 08:23:06