3

matplotlib ギャラリーでカスタム投影の例を見ています。南半球のみをプロットするように変更しようとしています。必要な [-pi/2,pi/2] 制限を [-pi/2,0] に調整しました。今私は見てきました:

def _gen_axes_patch(self):
    """
    Override this method to define the shape that is used for the
    background of the plot.  It should be a subclass of Patch.

    In this case, it is a Circle (that may be warped by the axes
    transform into an ellipse).  Any data and gridlines will be
    clipped to this shape.
    """
    #return Circle((0.5, 0.5), 0.5)
    return Wedge((0.5,0.5), 0.5, 180, 360)

def _gen_axes_spines(self):
    return {'custom_hammer':mspines.Spine.circular_spine(self,
                                                  (0.5, 0.5), 0.25)}

ご覧のとおり、Circle パッチを Wedge に置き換えました。現在の射影プロットは次のようになります。 射影プロット

スパインは引き続き円/楕円に従います。スパインがくさびの境界に従うように指定するにはどうすればよいですか?

背骨を修正する最善の方法がわからないので、どんな助けでも大歓迎です!

ありがとう、

アレックス

4

1 に答える 1

5

念のために言っておきますが、まだ Python を初めて使用する場合は、間違いなくプールの奥深くに飛び込んでいます。(そして、すぐに参加してくれてありがとう!)

あなたがやっていることは、かなり複雑なライブラリであるmatplotlibの内部の仕組みについてかなり詳細な知識を必要とします。

そうは言っても、それはすぐに学ぶ良い方法です!

このようなものについては、「パブリック」API だけでなく、物事がどのように構造化されているか という内部アーキテクチャを理解する必要があります。

このほとんどについては、掘り下げて「ソースを使用する」必要があります。どのプロジェクトでも、内部動作のドキュメントはコードそのものです。

そうは言っても、単純なケースの場合、それは非常に簡単です。

import numpy as np
from matplotlib.projections.geo import HammerAxes
import matplotlib.projections as mprojections
from matplotlib.axes import Axes
from matplotlib.patches import Wedge
import matplotlib.spines as mspines

class LowerHammerAxes(HammerAxes):
    name = 'lower_hammer'
    def cla(self):
        HammerAxes.cla(self)
        Axes.set_xlim(self, -np.pi, np.pi)
        Axes.set_ylim(self, -np.pi / 2.0, 0)

    def _gen_axes_patch(self):
        return Wedge((0.5, 0.5), 0.5, 180, 360)

    def _gen_axes_spines(self):
        path = Wedge((0, 0), 1.0, 180, 360).get_path()
        spine = mspines.Spine(self, 'circle', path)
        spine.set_patch_circle((0.5, 0.5), 0.5)
        return {'wedge':spine}

mprojections.register_projection(LowerHammerAxes)

if __name__ == '__main__':
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='lower_hammer')
    ax.grid(True)
    plt.show()

ここに画像の説明を入力

_get_axes_spinesメソッドを少し掘り下げてみましょう。

def _gen_axes_spines(self):
    """Return the spines for the axes."""
    # Make the path for the spines
    # We need the path, rather than the patch, thus the "get_path()"
    # The path is expected to be centered at 0,0, with radius of 1
    # It will be transformed by `Spine` when we initialize it
    path = Wedge((0, 0), 1.0, 180, 360).get_path()

    # We can fake a "wedge" spine without subclassing `Spine` by initializing 
    # it as a circular spine with the wedge path. 
    spine = mspines.Spine(self, 'circle', path)

    # This sets some attributes of the patch object. In this particular 
    # case, what it sets happens to be approriate for our "wedge spine"
    spine.set_patch_circle((0.5, 0.5), 0.5)

    # Spines in matplotlib are handled in a dict (normally, you'd have top,
    # left, right, and bottom, instead of just wedge). The name is arbitrary
    return {'wedge':spine}

これにはいくつかの問題があります。

  1. 物事が軸内で適切に中央に配置されていません
  2. Axes パッチは、Axes 内のスペースを適切に占有するために、少し大きくスケーリングできます。
  3. 地球全体のグリッド ラインを描画し、クリッピングします。「下」のくさびの内側にのみ描画する方が効率的です。

しかし、 がどのようHammerAxesに構造化されているかを見ると、これらの多くのこと (特に軸パッチのセンタリング) が効果的に変換にハードコーディングされていることがわかります。(コメントで言及されているように、これは「おもちゃ」の例であることを意図しており、常に地球全体を扱っていると仮定すると、変換の計算がはるかに簡単になります。)

これらを修正したい場合は、 のさまざまな変換のいくつかを微調整する必要がありますHammerAxes._set_lim_and_transforms

ただし、そのままでも十分に機能するので、それは読者の課題として残しておきます。:) (matplotlib の変換に関する詳細な知識が必要なため、その部分は少し難しいことに注意してください。)

于 2012-03-13T20:44:27.480 に答える