web-dev-qa-db-fra.com

Est-ce que matplotlib a une fonction pour dessiner des lignes diagonales dans les coordonnées des axes?

Les axes Matplotlib ont les fonctions axhline et axvline pour tracer des lignes horizontales ou verticales à une coordonnée y ou x donnée (respectivement) indépendamment de l'échelle de données sur un axe.

Existe-t-il une fonction similaire pour tracer une diagonale constante? Par exemple, si j'ai un diagramme de dispersion de variables ayant un domaine similaire, il est souvent utile de savoir si elles se situent au-dessus ou au-dessous de la ligne y = x:

mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1
f, ax = plt.subplots(figsize=(6, 6))
ax.scatter(x, y, c=".3")
ax.plot([-3, 3], [-3, 3], ls="--", c=".3")
ax.set(xlim=(-3, 3), ylim=(-3, 3))

enter image description here

Cela peut bien sûr être fait par programme en saisissant les limites des axes (ax.get_xlim(), etc.), mais a) nécessite quelques étapes supplémentaires et b) est fragile dans les cas où davantage de données pourraient se retrouver sur le tracé et déplacer les limites. (En fait, dans certains cas, le simple fait d’ajouter la ligne constante étend les axes).

Il serait préférable de faire, par exemple, ax.axdline(ls="--", c=".3"), mais on ne sait pas si quelque chose comme cela existe dans la base de code matplotlib. Tout ce que vous auriez besoin de faire serait de modifier le code axhline pour tracer [0, 1] dans axes les coordonnées pour x et y, je pense.

28
mwaskom

Tracer une ligne diagonale en partant du bas à gauche vers le haut à droite de l'écran est assez simple, vous pouvez simplement utiliser ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3"). La méthode ax.get_xlim() renverra simplement les valeurs actuelles de l'axe des x (et de la même manière pour l'axe des y).

Toutefois, si vous souhaitez zoomer à l'aide de votre graphique, la tâche devient un peu plus délicate, car la diagonale que vous avez tracée ne changera pas pour correspondre à vos nouveaux xlims et ylims. 

Dans ce cas, vous pouvez utiliser des rappels pour vérifier quand les xlims (ou les ylims) ont changé et modifier les données de votre ligne diagonale en conséquence (comme indiqué ci-dessous). J'ai trouvé les méthodes de rappel dans cet exemple . Des informations complémentaires peuvent également être trouvées ici

import numpy as np
import matplotlib.pyplot as plt

mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1

f, ax = plt.subplots(figsize=(6, 6))

ax.scatter(x, y, c=".3")
ax.set(xlim=(-3, 3), ylim=(-3, 3))

# Plot your initial diagonal line based on the starting
# xlims and ylims.
diag_line, = ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3")

def on_change(axes):
    # When this function is called it checks the current
    # values of xlim and ylim and modifies diag_line
    # accordingly.
    x_lims = ax.get_xlim()
    y_lims = ax.get_ylim()
    diag_line.set_data(x_lims, y_lims)

# Connect two callbacks to your axis instance.
# These will call the function "on_change" whenever
# xlim or ylim is changed.
ax.callbacks.connect('xlim_changed', on_change)
ax.callbacks.connect('ylim_changed', on_change)

plt.show()

Notez que si vous ne voulez pas que la diagonale change avec le zoom, supprimez tout ce qui se trouve en dessous de diag_line, = ax.plot(...

29
Ffisegydd

Je résous de cette façon:

ident = [0.0, 1.0]
plt.plot(ident,ident)
0
volperossa