web-dev-qa-db-fra.com

Comment zoomer une partie de l'image et l'insérer dans le même tracé dans matplotlib

Je voudrais agrandir une partie des données/image et la tracer à l'intérieur de la même figure. Il ressemble à cette figure.

zoomed plot

Est-il possible d'insérer une partie de l'image zoomée à l'intérieur du même tracé. Je pense qu'il est possible de dessiner une autre figure avec sous-intrigue mais elle dessine deux figures différentes. J'ai également lu pour ajouter un patch pour insérer un rectangle/cercle mais je ne sais pas s'il est utile d'insérer une partie de l'image dans la figure. Je charge essentiellement les données du fichier texte et les trace à l'aide d'une simple commande de tracé illustrée ci-dessous.

J'ai trouvé un exemple connexe de la galerie d'images matplotlib ici mais je ne sais pas comment cela fonctionne. Votre aide est tres apprecie.

from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])
plt.show()
43
Elect28

Jouer avec du code exécutable est l'un des moyens les plus rapides d'apprendre Python.

Commençons donc par le code de la galerie d'exemples matplotlib .

Compte tenu des commentaires dans le code, il semble que le code soit divisé en 4 strophes principales. La première strophe génère des données, la deuxième strophe génère le tracé principal, les troisième et quatrième strophes créent les axes en médaillon.

Nous savons comment générer des données et tracer le tracé principal, alors concentrons-nous sur la troisième strophe:

a = axes([.65, .6, .2, .2], axisbg='y')
n, bins, patches = hist(s, 400, normed=1)
title('Probability')
setp(a, xticks=[], yticks=[])

Copiez l'exemple de code dans un nouveau fichier, appelé, par exemple, test.py.

Que se passe-t-il si nous changeons le .65 En .3?

a = axes([.35, .6, .2, .2], axisbg='y')

Exécutez le script:

python test.py

Vous trouverez l'encart "Probabilité" déplacé vers la gauche. La fonction axes contrôle donc le placement de l'encart. Si vous jouez un peu plus avec les nombres, vous comprendrez que (.35, .6) est l'emplacement du coin inférieur gauche de l'encart et (.2, .2) est la largeur et la hauteur de l'encart. Les nombres vont de 0 à 1 et (0,0) est situé dans le coin inférieur gauche de la figure.

D'accord, maintenant nous cuisinons. Sur la ligne suivante, nous avons:

n, bins, patches = hist(s, 400, normed=1)

Vous pourriez reconnaître cela comme la commande matplotlib pour dessiner un histogramme , mais sinon, changer le nombre 400 à, disons, 10, produira une image avec un histogramme beaucoup plus gros, donc encore en jouant avec le vous comprendrez bientôt que cette ligne a quelque chose à voir avec l'image à l'intérieur de l'encart.

Vous voudrez appeler semilogx(data[3:8,1],data[3:8,2]) ici.

La ligne title('Probability') génère évidemment le texte au-dessus de l'encart.

Enfin, nous arrivons à setp(a, xticks=[], yticks=[]). Il n'y a pas de nombres avec lesquels jouer, alors que se passe-t-il si nous commentons la ligne entière en plaçant un # Au début de la ligne:

# setp(a, xticks=[], yticks=[])

Relancez le script. Oh! il y a maintenant beaucoup de graduations et d'étiquettes sur les axes en incrustation. Bien. Alors maintenant, nous savons que setp(a, xticks=[], yticks=[]) supprime les graduations et les étiquettes des axes a.

Maintenant, en théorie, vous disposez de suffisamment d'informations pour appliquer ce code à votre problème. Mais il y a une autre pierre d'achoppement potentielle: l'exemple matplotlib utilise from pylab import * Tandis que vous utilisez import matplotlib.pyplot as plt.

La FAQ de matplotlib indique que import matplotlib.pyplot as plt Est la façon recommandée d'utiliser matplotlib lors de l'écriture de scripts, tandis que from pylab import * Est destiné à être utilisé dans des sessions interactives. Donc, vous le faites de la bonne façon (même si je recommanderais d'utiliser import numpy as np Au lieu de from numpy import * Aussi).

Alors, comment convertir l'exemple matplotlib pour qu'il fonctionne avec import matplotlib.pyplot as plt?

Faire la conversion nécessite une certaine expérience avec matplotlib. Généralement, vous ajoutez simplement plt. Devant des noms nus comme axes et setp, mais parfois la fonction vient de numpy, et parfois l'appel doit provenir d'un objet axes, pas du module plt. Il faut de l'expérience pour savoir d'où viennent toutes ces fonctions. Googler les noms des fonctions avec "matplotlib" peut aider. La lecture d'un exemple de code peut créer de l'expérience, mais il n'y a pas de raccourci facile.

Ainsi, le code converti devient

ax2 = plt.axes([.65, .6, .2, .2], axisbg='y')
ax2.semilogx(t[3:8],s[3:8])
plt.setp(ax2, xticks=[], yticks=[])

Et vous pouvez l'utiliser dans votre code comme ceci:

from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])

ax2 = plt.axes([.65, .6, .2, .2], axisbg='y')
ax2.semilogx(data[3:8,1],data[3:8,2])
plt.setp(ax2, xticks=[], yticks=[])

plt.show()
30
unutbu

Le moyen le plus simple est de combiner "zoomed_inset_axes" et "mark_inset", dont la description et les exemples associés peuvent être trouvés ici: Présentation de la boîte à outils AxesGrid

enter image description here

26
kevin

La meilleure façon de le faire est d'utiliser mpl_toolkits.axes_grid1.inset_locator (partie de matplotlib).

Il y a un excellent exemple avec le code source ici: enter image description herehttps://github.com/NelleV/jhepc/tree/master/2013/entry1

22
David Ketcheson

Les étapes de base pour agrandir une partie d'une figure avec matplotlib

import numpy as np
from matplotlib import pyplot as plt

# Generate the main data
X = np.linspace(-6, 6, 1024)
Y = np.sinc(X)

# Generate data for the zoomed portion
X_detail = np.linspace(-3, 3, 1024)
Y_detail = np.sinc(X_detail)

# plot the main figure
plt.plot(X, Y, c = 'k')  

 # location for the zoomed portion 
sub_axes = plt.axes([.6, .6, .25, .25]) 

# plot the zoomed portion
sub_axes.plot(X_detail, Y_detail, c = 'k') 

# insert the zoomed figure
# plt.setp(sub_axes)

plt.show()

enter image description here

7
Amjad