matplotlib – ¿Cómo trazar un rectángulo orientado al azar (o cualquier forma)?

Deseo dibujar una línea cuyo ancho se especifique en la unidad de datos. En este caso, simplemente haciendo

plot(x, y, linewidth=1) 

fallaría, ya que el linewidth NO se especifica en la unidad de datos.

Para hacer esto, encuentro fill_between() , pero encuentro que todos los ejemplos dados aquí son del formato

 fill_between(x, y1, y2) 

lo que significa que la x siempre es compartida por y1 y y2 .

Entonces, ¿ qué y1 si y1 y y2 no comparten la misma x ?

por ejemplo, deseo llenar entre la line1=[(0, 0), (2, 2)] y la line2=[(-1, 1), (1, 3)] (esencialmente, forman un rectángulo). En este caso, quiero algo como

 fill_between(x1, x2, y1, y2) 

Al parecer, no está funcionando como se desea:

 In [132]: x1 = [0,2] .....: x2 = [-1, 1] .....: y1 = [0,2] .....: y2 = [1,3] .....: fill_between(x1, x2, y1, y2) .....: Out[132]:  

introduzca la descripción de la imagen aquí

¿Cómo debo trazar en este caso?

¡Buena pregunta! Le sugiero que no se limite en la función fill_between . Siempre me parece beneficioso mirar profundamente dentro de las cosas. Vamos a sumergirnos en la esencia del dibujo de Python.

El objeto que subyace a todos los objetos matplotlib.patch es la Path .

Por lo tanto, si dominas el Path , básicamente puedes dibujar lo que quieras de cualquier manera. Veamos ahora cómo logramos tu objective con el Path mágico.

Para obtener el rectángulo que mencionó en la pregunta, solo se necesita un poco de adaptación en el ejemplo.

 import matplotlib.pyplot as plt from matplotlib.path import Path import matplotlib.patches as patches verts = [(0., 0.), # left, bottom (-1., 1.), # left, top (1., 3.), # right, top (2., 2.), # right, bottom (0., 0.),] # ignored codes = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY,] path = Path(verts, codes) fig = plt.figure() ax = fig.add_subplot(111) patch = patches.PathPatch(path, facecolor='orange', lw=2) ax.add_patch(patch) ax.axis('equal') plt.show() 

Creo que el código es tan directo y autoexplicativo que no necesito desperdiciar mis palabras en él. Solo copie y pegue y ejecútelo, obtendrá esto, exactamente lo que desea.

introduzca la descripción de la imagen aquí

Aún más simple, matplotlib.patches.Rectangle

 rect = matplotlib.patches.Rectangle((.25, .25), .25, .5, angle=45) plt.gca().add_patch(rect) plt.draw() 

En lugar de trazar las líneas, puede dibujar el área rellena como un polígono . Para hacer esto, necesita concatenar x1 con el reverso de x2 y hacer lo mismo para y1 y y2 . Algo como esto:

 In [1]: from pylab import * In [2]: x1 = arange(0,11,2) In [3]: x2 = arange(0,11) In [4]: y1 = x1**2+1 In [5]: y2 = x2**2-1 In [6]: xy = c_[r_[x1,x2[::-1]], r_[y1,y2[::-1]]] In [7]: ax = subplot(111) # we need an axis first In [8]: ax.add_patch(Polygon(xy)) Out[8]:  In [9]: axis([0,10,-10,110]) # axis does not automatically zoom to a patch Out[9]: [0, 10, -10, 110] In [10]: show()