2014-07-11 7 views
1

J'essaie de tracer des points sur un contour en utilisant Matplotlib.Tracer des points sur le contour - Matplotlib/Python

J'ai un champ scalaire à partir duquel je veux tracer le contour. Cependant, mon ndarray a une dimension 0 x 20, mais mon espace réel varie de 4 à 4.

Je peux tracer ce contour en utilisant ce morceau de code:

x, y = numpy.mgrid[-4:4:20*1j, -4:4:20*1j] 

# Draw the scalar field level curves 
cs = plt.contour(scalar_field, extent=[-4, 4, -4, 4]) 
plt.clabel(cs, inline=1, fontsize=10) 

Le problème est Parce que je dois tracer quelques points sur cette intrigue, et que ces points sont obtenus en utilisant le ndarray, c'est-à-dire, je reçois des points variant en tant que dimension de ce tableau.

J'ai essayé de tracer ces points en utilisant ce code:

def plot_singularities(x_dim, y_dim, steps, scalar_field, min_points, max_points, file_path): 
    """ 
    :param x_dim : the x dimension of the scalar field 
    :param y_dim : the y dimension of the scalar field 
    :param steps : the discretization of the scalar field 
    :param file_path : the path to save the data 
    :param scalar_field : the scalar_field to be plot 
    :param min_points : a set (x, y) of min points of the scalar field 
    :param max_points : a set (x, y) of max points of the scalar field 
    """ 
    min_points_x = min_points[0] 
    min_points_y = min_points[1] 
    max_points_x = max_points[0] 
    max_points_y = max_points[1] 

    plt.figure() 

    x, y = numpy.mgrid[-x_dim:x_dim:steps*1j, -y_dim:y_dim:steps*1j] 

    # Draw the scalar field level curves 
    cs = plt.contour(scalar_field, extent=[-x_dim, x_dim, -y_dim, y_dim]) 
    plt.clabel(cs, inline=1, fontsize=10) 

    # Draw the min points 
    plt.plot(min_points_x, min_points_y, 'ro') 

    # Draw the max points 
    plt.plot(max_points_x, max_points_y, 'bo') 

    plt.savefig(file_path + '.png', dpi=100) 
    plt.close() 

Mais j'ai cette image:

enter image description here

ce qui est inexact.

Si je change cette ligne:

cs = plt.contour(scalar_field, extent=[-x_dim, x_dim, -y_dim, y_dim]) 

Pour que l'on:

cs = plt.contour(scalar_field) 

enter image description here

je reçois le comportement souhaité, mais l'étendue ne montre pas mon vrai espace de données , mais la dimension ndarray.

Enfin, si je ne conspire pas ces points (commentaire l'intrigue() lignes), je peux les degrés que je veux:

enter image description here

Mais je dois tracer les points. Les deux données se trouvent dans le même espace. Mais la fonction contour() me permet de spécifier la grille. Je pourrais trouver une manière de le faire en traçant les points.

Je me demande comment puis-je définir correctement les extensions comme je le souhaite.

Merci d'avance.

+0

Il serait utile de savoir ce que vous attendiez. Que devrait être "l'espace de données"? Les points et le contour sont-ils incorrects ou juste le contour? – amd

+0

Si vous regardez la deuxième image, elle est correcte (les graphiques). Cependant, il montre les étendues comme les dimensions de ndarray (de 0 à 20). Je voudrais montrer qu'il varie d'un espace de mes données (avec le centre en 0,0 et variant de -4 à 4). J'appelle mon "espace de données" comme une analogie avec les concepts de CG à l'espace d'image (ndarray) et l'espace du monde (mon espace de données réel). – pceccon

Répondre

2

Si vous ne fournissez pas x et y données correspondant au champ scalaire, contour utilise des valeurs entières jusqu'à la taille du tableau. C'est pourquoi les axes affichent la dimension du tableau. Les paramètres extent doivent donner les valeurs minimum et maximum x et y; Je suppose que c'est ce que vous entendez par "espace de données"."Donc, l'appel à contour serait:

contour(scalar_field,extent=[-4,4,-4,4]) 

Cela peut être reproduit en spécifiant x et y données.

contour(numpy.linspace(-4,4,20),numpy.linspace(-4,4,20),scalar_field) 

Ensuite, le contour ressemble exactement comme dans votre première parcelle je suppose que la raison pour laquelle cette est incorrecte parce que les points min et max ne sont pas au bon endroit.En fonction de l'information que vous avez donnée, c'est parce que min_points et max_points que vous passez à votre fonction sont indices au tableau scalar_field, donc ils correspondent à des entiers, pas les valeurs réelles x et y. Essayez d'utiliser ces indices pour accéder aux x et y points en définissant:

x=numpy.linspace(-4,4,20) 
y=numpy.linspace(-4,4,20) 

Par exemple, si vous avez un min point de (0,1), il correspondrait à (x[0], y[1]). Je pense qu'une chose similaire peut être faite avec le mgrid, mais je ne l'ai jamais utilisé moi-même.

+0

N'aurait pas pu dire mieux moi-même :) – Ajean

+0

Merci! Comme je viens de le faire pour @Ajean, je sais que c'étaient des indices et que c'était le problème (désolé si je ne pouvais pas m'exprimer dans le bon sens). Je cherchais une façon intelligente de faire cette conversion dans Matplolib/Python. Merci beaucoup! – pceccon

0

Vous souhaitez tracer à la fois le contour et les points dans l'espace de données réel, oui? plt.contour prendra les valeurs x et y associées au tableau 2D que vous possédez et tracera correctement les axes.

xvals = -x_dim:x_dim:step # I'm not sure about these ... but you get the idea 
yvals = -y_dim:y_dim_step 
plt.contour(xvals, yvals, scalar_field) 
+0

Si je fais juste cela, je reçois la première image, qui ne respecte pas l'espace que je veux quand je trace les points. – pceccon

+0

Etes-vous sûr que les points que vous tracez sont dans le bon espace, alors? Il semble que vous traçiez les valeurs réelles avec une chose et les indices avec l'autre. – Ajean

+0

Ils sont tous deux dans le même espace. Je change d'étendue en tant que paramètre lors du tracé du contour, mais je ne sais pas comment le faire lorsque je trace les points. – pceccon

Questions connexes