2017-07-04 1 views
1

私は次のことを正しく描く方法を理解しようとしています。matplotlibで回転矩形のグラフスティックを適切に描く方法は?

は、私は2つのノード、R^2で、すなわち2点、すなわち、SRC =(x1、y1)とDST =(X2、Y2)を有すると言うことができます。

私はそれらの間のエッジ/線を引くしたいのですが、箱から始まります。

これは私がは、TikZで作成した例です。 enter image description here

srcとdestがこれらのノードの中心です。彼らはまた異なる高さにあることができることに注意してください。問題は、patch.Rectangleを使ってボックスを構築しようとすると、それを回転させてサイズを変更することです。あなたが棒のように回転した矩形とグラフのための満たされたrectangeを使用して満足している場合は、事前

答えて

2

おかげで、これは、散布ポイントと厚いシンプルなラインでエミュレートすることができますグラフのエッジ。

import matplotlib.pyplot as plt 
import numpy as np 

def plot_spec_line(src, dst, length=0.3, srctext="v", dsttext="w", 
        ax=None, color="k", textcolor="k"): 
    if not ax: ax=plt.gca() 
    lend=src+(dst-src)*length 
    ax.plot([src[0],lend[0]], [src[1],lend[1]], lw=24,solid_capstyle="butt", zorder=1, color=color) 
    ax.plot([src[0],dst[0]], [src[1],dst[1]], lw=2,solid_capstyle="butt", zorder=0, color=color) 
    ax.scatter([src[0],dst[0]], [src[1],dst[1]], s=24**2, marker="o", lw=2, edgecolors=color, c="w", zorder=2) 
    ax.text(src[0],src[1], srctext, fontsize=12, ha="center", va="center", zorder=3, color=textcolor) 
    ax.text(dst[0],dst[1], dsttext, fontsize=12, ha="center", va="center", zorder=3, color=textcolor) 

s = np.array([1,1]) 
d = np.array([3,2])  
plot_spec_line(s, d, length=0.3, srctext="v", dsttext="w") 

s = np.array([1.5,0.9]) 
d = np.array([2.8,1.2])  
plot_spec_line(s, d, length=0.2, srctext="a", dsttext="b", color="gray") 

s = np.array([1,2]) 
d = np.array([2,1.9])  
plot_spec_line(s, d, length=0.7, srctext="X", dsttext="Y", textcolor="limegreen", color="limegreen") 

plt.margins(0.2) 
plt.show() 

enter image description here


充填か、よりimporatantlyことができる矩形を得るために、エッジを持っている、あなたが Rectangleを使用することができます。 rotate a rectangleには、適切なトランスフォームを設定することができます。 これは、長方形と円が歪んでいないように、同じアスペクト比のプロットを使用するのが理にかなっています。私がまさに必要である

import matplotlib.pyplot as plt 
import matplotlib.transforms 
import numpy as np 

def plot_spec_line(src, dst, length=0.3, radius=0.1, srctext="v", dsttext="w", 
        ax=None, color="k", textcolor="k", reccolor="w", lw=1): 
    if not ax: ax=plt.gca() 
    lend=np.sqrt(np.sum(((dst-src)*length)**2)) 
    s = dst-src 
    angle = np.rad2deg(np.arctan2(s[1],s[0])) 
    delta = np.array([0,radius]) 
    tr = matplotlib.transforms.Affine2D().rotate_deg_around(src[0],src[1], angle) 
    t = tr + ax.transData 
    rec = plt.Rectangle(src-delta, width=lend, height=radius*2, ec=color,facecolor=reccolor, transform=t, linewidth=lw) 
    ax.add_patch(rec) 
    ax.plot([src[0],dst[0]], [src[1],dst[1]], lw=lw,solid_capstyle="butt", zorder=0, color=color) 
    circ1= plt.Circle(src, radius=radius, fill=True, facecolor="w", edgecolor=color, lw=lw) 
    circ2= plt.Circle(dst, radius=radius, fill=True, facecolor="w", edgecolor=color, lw=lw) 
    ax.add_patch(circ1) 
    ax.add_patch(circ2) 
    ax.text(src[0],src[1], srctext, fontsize=12, ha="center", va="center", zorder=3, color=textcolor) 
    ax.text(dst[0],dst[1], dsttext, fontsize=12, ha="center", va="center", zorder=3, color=textcolor) 

s = np.array([1,1]) 
d = np.array([3,2])  
plot_spec_line(s, d, length=0.3, srctext="v", dsttext="w", radius=0.06, 
       reccolor="plum",) 

s = np.array([1.5,0.9]) 
d = np.array([2.8,1.2])  
plot_spec_line(s, d, length=0.2, srctext="a", dsttext="b", color="gray", lw=2.5) 

s = np.array([1,2]) 
d = np.array([2,1.9])  
plot_spec_line(s, d, length=0.7, srctext="X", dsttext="Y", textcolor="limegreen", 
       reccolor="palegreen", color="limegreen") 

plt.margins(0.2) 
plt.gca().set_aspect("equal") 
plt.show() 

enter image description here

+0

感謝。 – Doc

+0

同じものを塗りつぶさずに描く方法を知っているのはうれしいですが。アプローチは何ができますか? – Doc

+1

ここでのトリックは、定義ごとに "塗りつぶし"という行を使用することです。塗りつぶされていない四角形が必要な場合は、(a) 'Rectangle'を使用して回転させるか、(b)' PathPatch'を使うという2つのオプションがあります。最初のケースでは、回転ポイントを見つけることが課題です.2番目のケースでは、コーナーポイントの座標を計算する必要があります。私はソリューションのひとつであなたを助けることができましたが、私はまず最初に、上記の(満たされた)ソリューションがあなたが望むものではないことを確かめたかったのです。 – ImportanceOfBeingErnest