2016-04-22 30 views
2

Ich muss Halbellipsen (oder um genau zu sein, halbelliptische Platten), daher kann ich Matplotlib nicht verwenden, um eine elliptical arc zu plotten.Wie man Halbellipsen in Python zeichnet?

Ich fand OpenCV kann dies mit dieser Syntax tun: cv2.Ellipse(img, center, axes, angle, start_angle, end_angle, color, thickness=1, lineType=8, shift=0), aber es gibt eine Sache, die mich wirklich stört. Ich möchte Standard-X- und Y-Koordinaten verwenden, keine Pixel. Außerdem muss ich halbe Ellipsen mit nicht ganzzahligem Radius zeichnen, und es scheint, dass OpenCV das nicht kann (aus demselben Grund, Pixelkoordinaten zu haben).

Also, ich brauche einen Code, der tun kann, was OpenCV tut (mit der gleichen Struktur), aber ohne dass ich in Pixel arbeiten muss.

Antwort

2

können Sie verwenden matplotlib arc ist Sie wollten sie nicht ausgefüllt. Für einen gefüllten Bogen können Sie die akzeptierte Lösung here verwenden, in denen ein allgemeiner Patch definiert ist und verbinden sich mit dem matplotlib Ellipse example,

import matplotlib.patches as mpatches 
import matplotlib.pyplot as plt 
import numpy.random as rnd 
import numpy as np 

def arc_patch(xy, width, height, theta1=0., theta2=180., resolution=50, **kwargs): 

    # generate the points 
    theta = np.linspace(np.radians(theta1), np.radians(theta2), resolution) 
    points = np.vstack((width*np.cos(theta) + xy[0], 
         height*np.sin(theta) + xy[1])) 
    # build the polygon and add it to the axes 
    poly = mpatches.Polygon(points.T, closed=True, **kwargs) 

    return poly 

NUM = 10 
arcs = [] 
for i in range(NUM): 
    r = rnd.rand()*360. 
    arcs.append(arc_patch(xy=rnd.rand(2)*10, width=1., 
       height=1., theta1=r, theta2=r+180.)) 

# axis settings 
fig, ax = plt.subplots(1,1) 
for a in arcs: 
    ax.add_artist(a) 
    a.set_clip_box(ax.bbox) 
    a.set_alpha(0.5) 
    a.set_facecolor(rnd.rand(3)) 

ax.set_xlim(0, 10) 
ax.set_ylim(0, 10) 

plt.show() 

das wie folgt aussieht, enter image description here

+0

FYI, 'matplotlib.patches.Arc' kann gefüllte Halbellipsen machen. –

+0

Haben Sie eine Referenz für diesen @Syrtis Major? Die offiziellen Dokumente für 'matplotlib.patches.Arc' hier: http://matplotlib.org/api/patches_api.html#module-matplotlib.patches sagt explizit" Weil es verschiedene Optimierungen durchführt, kann es nicht gefüllt werden. " –

+0

Ah, ich habe die Dokumente nicht bemerkt, aber probier es einfach (siehe Antwort unten). Ich bin mir nicht sicher warum, vielleicht ist die Dokumentation etwas veraltet? –

2

Verwenden matplotlib.patches.Arc können Halbellipsen machen, geben Sie einfach die Schlüsselwörter theta1=0.0, theta2=180.0 (oder 90-270). Ich habe eine Wrapper-Funktion mit dem Namen arcs für die Erstellung eines Streudiagramms von Arc s geschrieben. Es verwendet die PatchCollection, sollte eine bessere Leistung haben und Farbbalken aktivieren. Sie finden es unter gist (link).

Hier ist ein Beispiel:

a = np.arange(11) 
arcs(a, a, w=4, h=a, rot=a*30, theta1=0.0, theta2=180.0, 
    c=a, alpha=0.5, edgecolor='none') 
plt.colorbar() 

enter image description here


Eine kurze Einführung von arcs unten auf Vollständigkeit gebucht wird wie Ed Smith vorgeschlagen.

def arcs(x, y, w, h, rot=0.0, theta1=0.0, theta2=360.0, 
     c='b', **kwargs): 
    import numpy as np 
    import matplotlib.pyplot as plt 
    from matplotlib.patches import Arc 
    from matplotlib.collections import PatchCollection 

    if np.isscalar(c): 
     kwargs.setdefault('color', c) 
     c = None 

    zipped = np.broadcast(x, y, w, h, rot, theta1, theta2) 
    patches = [Arc((x_, y_), w_, h_, rot_, t1_, t2_) 
       for x_, y_, w_, h_, rot_, t1_, t2_ in zipped] 
    collection = PatchCollection(patches, **kwargs) 

    if c is not None: 
     c = np.broadcast_to(c, zipped.shape).ravel() 
     collection.set_array(c) 

    ax = plt.gca() 
    ax.add_collection(collection) 
    return collection 

Die Vollversion kann im Kern (link) finden.

+0

Ihre Lösung sieht gut aus. Ist es möglich, den minimalen Code für ein Beispiel der Verwendung von PatchCollections herauszulösen, um hier eine eigenständige Antwort zu geben? –

Verwandte Themen