2012-01-30 14 views
7

Estoy tratando de hacer una trama 2D usando pyplot. Estoy leyendo en un archivo con varias columnas, cada una de las cuales contiene alrededor de 100 valores entre 1 y 10. Estoy trazando la columna 5 contra la columna 6, lo cual está bien.Matplotlib - puntos de etiquetado (x, y) en una línea con un valor z

Lo que también quiero hacer es etiquetar la línea resultante con valores enteros de la columna 0. Entonces la línea tendrá 11 puntos, en las posiciones (x, y) donde la columna 0 es un número entero. También me gustaría que esos puntos se etiqueten con ese número entero.

Realmente agradecería cualquier ayuda con esto, ¡me está volviendo loco!

+0

¿qué ha intentado hasta ahora? En otras palabras, ¿tiene algún código de ejemplo que muestre qué funciona y qué no funciona (o dónde está perdido)? Tenga en cuenta que puede formatear el código cuando edita su pregunta ... – Yann

+2

¿Qué ha intentado? ¿Puedes dar un fragmento de código hasta el momento? 'vals [vals% 1 == 0]' encuentra enteros, y puede usar ['matplotlib.pyplot.text'] (http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.text) dibujar texto 'plt.text (x, y, str (y))' para todos sus pares 'x, y' –

Respuesta

26

De su pregunta, no estoy 100% claro exactamente lo que quiere hacer.

¿Simplemente desea etiquetar cada vértice en una línea? ¿O solo quieres etiquetar vértices que son enteros? ¿O desea interpolar dónde "cruces" enteros se alinearían a lo largo de la línea y los etiquetaría?

En primer lugar, para cargar su archivo de texto, busque en numpy.loadtxt, si no lo está. En su caso particular, se podría hacer algo como:

z, x, y = np.loadtxt('data.txt', usecols=[0, 5, 6]).T 

En cualquier caso, como un ejemplo rápido de la opción más simple (el etiquetado de cada vértice):

import numpy as np 
import matplotlib.pyplot as plt 

x = np.arange(10) 
y = 2 * x 
z = x ** 2 

fig, ax = plt.subplots() 
ax.plot(x, y, 'bo-') 

for X, Y, Z in zip(x, y, z): 
    # Annotate the points 5 _points_ above and to the left of the vertex 
    ax.annotate('{}'.format(Z), xy=(X,Y), xytext=(-5, 5), ha='right', 
       textcoords='offset points') 

plt.show() 

enter image description here

Ahora, para la segunda opción, podríamos tener algo más como esto (Similar a lo que se sugirió @ mathematical.coffee):

import numpy as np 
import matplotlib.pyplot as plt 

x = np.arange(-0.6, 5.6, 0.2) 
y = 2 * x 
z = x**2 

fig, ax = plt.subplots() 
ax.plot(x, y, 'bo-') 

# Note the threshold... I'm assuming you want 1.000001 to be considered an int. 
# Otherwise, you'd use "z % 1 == 0", but beware exact float comparisons!! 
integers = z % 1 < 1e-6 
for (X, Y, Z) in zip(x[integers], y[integers], z[integers]): 
    ax.annotate('{:.0f}'.format(Z), xy=(X,Y), xytext=(-10, 10), ha='right', 
       textcoords='offset points', 
       arrowprops=dict(arrowstyle='->', shrinkA=0)) 

plt.show() 

enter image description here

+0

Me aparece un error aquí: 'TypeError: __init __() falta 1 argumento de posición requerido: 's'' en esta línea' arrowprops = dict (arrowstyle =' -> ', shrinkA = 0) ' – saitam

Cuestiones relacionadas