3

私はmatplotlibとBasemapに慣れようとしています。まず、データがある特定のグリッドに一致するグリーンランドの画像を生成しようとしています。

以下の恐ろしい詳細は私の問題を説明しています:私は希望する投影/領域に一致する適切なサイズの画像を作成することができません。

一致させたいプロジェクションとグリッド:Proj4文字列としてのプロジェクション:"+proj=stere +lat_0=90 +lon_0=-45 +lat_ts=70 +ellps=WGS84 +datum=WGS84 +units=m"

グリッドによって定義される領域は、800x1400 2000mの解像度のグリッドです。ここで、LowerLeft Corner(m)の外縁:-700,000。、-3,400,000。右上隅の外縁(m):900,000。、-600,000。=>(-700,000 + 2000 * 800、-3,400,000 + 2000 * 1400)

ベースマップでは、ステレオ投影のコーナーをメートル-xyで指定できないため、これらを緯度/経度に変換する必要があります。

> gdaltransform -s_srs "+proj=stere +lat_0=90 +lon_0=-45 +lat_ts=70 +ellps=WGS84 +datum=WGS84 +units=m" -t_srs "+proj=latlong"`
-700000 -3400000
-56.6336339989404 58.7244253840871 0
900000 -600000
11.3099324740202 80.0389929796586 0

これで、800x1400のイメージを作成するためのすべての情報が得られるはずです。

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt

def create_map():
    fig = plt.figure(1, figsize=(8, 14), frameon=False, dpi=100)
    fig.add_axes([0, 0, 1, 1])

    m = Basemap(resolution="i",
                projection='stere', lat_ts=70, lat_0=90., lon_0=-45.,
                llcrnrlon=-56.6336339989404, llcrnrlat=58.7244253840871,
                urcrnrlon=11.3099324740202, urcrnrlat=80.0389929796586,
                rsphere=(6378137.0, 6356752.3142))

    m.drawcoastlines()
    m.fillcontinents(color='#c1c1c1')
    m.drawmapboundary(fill_color='#6587ad', linewidth=0.0)
    plt.savefig('greenland.png', pad_inches=0.0, bbox_inches='tight')

if __name__ == '__main__':
    create_map()

私が直面している問題は、これを行うと、800x1399の画像が得られることです。bbox_inches='tight'コマンドにを含めない場合plt.savefig、(編集)下端(編集)に沿って非表示のピクセルの単一のストリップを含む800x1400の画像が得られます。

ベースマップを正しく設定していることを確認できるように、誰かが私を助けてくれますか?簡単なトリックが足りないような気がしますが、期待するサイズの画像が得られないのはおかしいです。

いつものように、よろしくお願いします。

4

1 に答える 1

1

これはmatplotlibのバグの結果である可能性があります。Jeff Whitakerが調べて、正しく見えると言ったので、Basemapを使用せずにこの動作を再現しようとしましたが、できました。

データ値の側面により、出力画像のサイズが間違っている可能性があります。

問題を示すコードを次に示します。誤警報でごめんなさい。

# rectangle.py   --
import matplotlib.pyplot as plt


def create_image():
    fig = plt.figure(1, figsize=(8, 14), frameon=False, dpi=100)
    fig.add_axes([0, 0, 1, 1])
    ax = plt.gca()

    # This isn't necessary to create the issue unless you want to see the
    # transparent pixels at bottom.

    # for spine in ax.spines.values():
    #     spine.set_linewidth(0.0)

    limb = ax.axesPatch
    limb.set_facecolor('#6587ad')

    x1 = 0.0
    y1 = 0.0
    x2 = 16.

    # Use this line and get what I was expecting:
    #    y2 = 27.999999999999994671   # produces 800 x 1400 image

    # Use this line and get the wrong size
    y2 = 27.999999999999994670   # produces (wrong?) 800 x 1399 image

    corners = ((x1, y1), (x2, y2))
    ax.update_datalim(corners)
    ax.set_xlim((x1, x2))
    ax.set_ylim((y1, y2))

    ax.set_aspect('equal', anchor='C')
    ax.set_xticks([])
    ax.set_yticks([])

    plt.savefig('rectangle.png', pad_inches=0.0, bbox_inches='tight')

    # If you use this below, the file size is correct, but there is a single
    # line transparent pixels along the bottom of the image if you set the
    # linewidth to zero...

    #  plt.savefig('rectangle.png', pad_inches=0.0)


if __name__ == '__main__':
    create_image()
于 2012-11-16T20:32:51.680 に答える