2016-04-22 37 views
2

私は半楕円を描く必要があります(正確には半楕円形のディスクなので、elliptical arcをプロットするためにmatplotlibを使うことはできません)。Pythonで半楕円をプロットする方法は?

私はOpenCVがこの構文でこれを行うことができます:cv2.Ellipse(img, center, axes, angle, start_angle, end_angle, color, thickness=1, lineType=8, shift=0)しかし、本当に私を悩ますことが1つあります。ピクセルではなく標準のx座標とy座標を使いたい。また、非整数​​の半径を持つ半楕円をプロットする必要があります.OpenCVはそうすることはできません(ピクセル座標を持つのと同じ理由で)。

OpenCVが(同じangle + start_angle + end_angle構造で)行うことができるコードが必要ですが、ピクセルで作業する必要はありません。

答えて

2

あなたはmatplotlibのarcを使用することができますが、あなたがそれらを充填したくなかったです。満たされたアークのために、あなたは一般的なパッチが定義されている受け入れソリューションhereを使用することができますし、matplotlibの楕円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() 
以下のように見える

enter image description here

+0

FYI、 'matplotlib.patches.Arc'は半角の楕円を塗りつぶすことができます。 –

+0

この@Syrtis Majorのリファレンスがありますか? 'matplotlib.patches.Arc'の公式文書はここにあります:http://matplotlib.org/api/patches_api.html#module-matplotlib.patchesは"様々な最適化を実行するので、それを満たすことはできません "と明示的に言います。 –

+0

ああ、私はドキュメントに気づいていませんでしたが、試しました(下記の回答を参照)。私はなぜ、おそらくドキュメントは少し古くなっているのか分からないのですか? –

2

使用matplotlib.patches.Arcはちょうどキーワードtheta1=0.0, theta2=180.0(270または90)を指定し、半楕円を作ることができます。 散布図をArcにするために、arcsというラッパー関数を記述しました。 PatchCollectionを使用し、パフォーマンスが向上し、カラーバーを有効にする必要があります。 gist (link)で見つけることができます。ここで

は例です:エド・スミスが提案されているようarcs

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


簡単な実装は、完全を期すために、以下の掲示されます。

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 

フルバージョンは、gist (link)にあります。

+0

あなたのソリューションはよさそうだ。 PatchCollectionsを使用してここに自己回答を与えるための最小限のコードを抽出することは可能ですか? –

関連する問題