1

楕円をマーカーとしてプロットを作成したいと思います。これは、今のところ実際には円である1つの大きな楕円を作成するサンプルコードです。

#! /usr/bin/env python3.2
import numpy as np
import pylab
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib.patches import Ellipse

PlotFileName="test.pdf"
pdf = PdfPages(PlotFileName)
fig=plt.figure(1)
ax1=fig.add_subplot(111)
x_lim=3
plt.xlim([0,x_lim])
plt.ylim([0,x_lim])

F=pylab.gcf()
DefSize = F.get_size_inches()

#These lines have a true angle of 45 degrees, only as a reference:
offset_along_x=x_lim-(x_lim/ax_ratio)
ax1.plot([offset_along_x/2, x_lim-(offset_along_x/2)], [0, x_lim], "b")
ax1.plot([offset_along_x/2, x_lim-(offset_along_x/2)], [x_lim, 0], "b")

e=0.0
theta=0
maj_ax=2
min_ax=maj_ax*np.sqrt(1-e**2)
xconst=(DefSize[1]/DefSize[0])*np.cos(theta*np.pi/180)-np.sin(theta*np.pi/180)
yconst=np.cos(theta*np.pi/180)+(DefSize[1]/DefSize[0])*np.sin(theta*np.pi/180)
print("xconstant= {}".format(xconst))
print("yconstant= {}".format(yconst))
ax1.add_artist(Ellipse((x_lim/2, x_lim/2), xconst*maj_ax, yconst*min_ax, angle=theta, facecolor="green", edgecolor="black",zorder=2, alpha=0.5))

pdf.savefig(fig)
pdf.close()
plt.close()

この単純化されたケースでax1.axis("equal")は、純粋な円が得られますが、私の最終的なプロットでは、このコマンドはプロット全体を台無しにします(スケールは等しくありません)。なので、を使わずに汎用の楕円ツールを作りたいですax1.axis("equal")。ご覧のとおり、このプログラムでは、主軸の偏心と傾斜角度を設定できます。

問題: 問題は、matplotlibが画像をどのように回転させるかがわからないことのようです。thetahereの値を0または90以外の値に変更すると、オブジェクトは円ではなくなります。出力は円でax1.axis("equal")、値が何であるかが重要になりますtheta。だから私の最初の問題はこれです:変更中に出力を円として維持するにはどうすればよいですかtheta?これを修正すると、楕円でも機能すると思います。誰かがこれを手伝ってくれませんか?とても感謝しております。

4

1 に答える 1

3

matplotlib では、日食の位置と形状は、最初に高さと幅にスケーリングしてから、その中心を中心に回転させてから、必要な位置に変換することによって設定されます。したがって、高さを回転およびスケーリングし、前にモークすることはできますが (スクリプトのように)、正確に正しくするのは困難です (おそらく、回転をスケーリングおよび反転する必要がありますが、私の変換計算は錆びています)。

楕円の形を正しくスケーリングしたい場合は、Ellipse クラスをサブクラス化し、_recompute_transform関数を再定義する必要があります。

from matplotlib import transforms

class TransformedEllipse(Ellipse):

    def __init__(self, xy, width, height, angle=0.0, fix_x = 1.0, **kwargs):
        Ellipse.__init__(self, xy, width, height, angle, **kwargs)

        self.fix_x = fix_x

    def _recompute_transform(self):

        center = (self.convert_xunits(self.center[0]),
                  self.convert_yunits(self.center[1]))
        width = self.convert_xunits(self.width)
        height = self.convert_yunits(self.height)
        self._patch_transform = transforms.Affine2D() \
            .scale(width * 0.5, height * 0.5) \
            .rotate_deg(self.angle) \
            .scale(self.fix_x, 1) \
            .translate(*center)

次のように使用します。

fix_x = DefSize[1]/DefSize[0]/ax_ratio

ellipse = TransformedEllipse((x_lim/2.0, x_lim/2.0), maj_ax, min_ax, angle=theta, facecolor="green", edgecolor="black",zorder=2, alpha=0.5, fix_x = fix_x)

PS 私は!であると仮定ax_ratioします。y_lim / x_lim

于 2012-07-05T12:11:15.373 に答える