(2020/10/20追記)
Cartopy 0.18.0 では上記バグは修正されているようです.
環境
Python 3.7.4
Matplotlib 3.1.1
Cartopy 0.17.0
何が起きた?
なんと表現したらいいかわからないので,まず問題の図を紹介します.
データはとある気象データ(JRA-55, 200hPaジオポテンシャル高度[gpm])です.
コンター(等値線)が正常に描画されず,経度0度の付近で一斉に逆向き?に同じ緯度を回転してしまいます.図のように,極点を含む投影図(ここではccrs.AzimuthalEquidistant())で発生する問題と認識しています.
あるStackoverflowの記事によると,経度の配列も忘れずに東西にcyclicさせよとありますが,元々してるんだよなぁ.
(add_cyclic_pointはこちらの記事でも視覚的に説明されています.)
import numpy as np
from cartopy.util import add_cyclic_point
# 色々省略
lon = np.arange(0, 360, 1.25) #ここでは358.75まで
f_cycle, lons = add_cyclic_point(f, cood=lon) #360まで拡張,経度情報はlonsへ格納,fは描くデータ
逆にadd_cyclic_pointをせずに描画すると,
”逆向き一周”の問題は回避されましたが,経度0度付近でコンターに隙間が生まれます.
自分なりに調べたものの,現在この問題を回避する方法を見つけられていません.
2018年のStackoverflowの記事ではこの問題にCartopyのデベロッパも協力しているようですが,その後どうなったのでしょうか..(最新版では解決されているかもしれません)
妥協案
として考えたのが,ラベルをつけるコンターを限定的にしてそのコンターはadd_cyclic_pointさせない,という方法です.
必要最低限のラベルをつけることができますが,ラベルのついたコンターはやはり経度0度付近で途切れてしまいます.
# ラベル用の数列
lev1 = np.arrange(0, 200001, 100) #狭めの間隔
lev1n = lev1 #lev1を残す場合のための複製
lev5 = np.arrange(0, 200001, 400) #広めの間隔
for l in lev5:
lev1n = lev1n[~(lev1n==l)] #lev1(lev1n)からlev5と同一な要素を取り除く
''' 中身を列挙すると
lev1: 0, 100, 200, 300, 400, 500, 600, ...
lev5: 0, 400, ...
lev1n: 100, 200, 300, 500, 600, ...
'''
# lev1nを使ったコンター,add_cyclic_pointあり,ラベルなし
c1 = ax.contour(lons, lat, f_cycle, lev1n, linewidth=0.8, transform=ccrs.PlateCarree())
# lev5を使ったコンター,add_cyclic_pointなし,ラベルあり
c5 = ax.contour(lon, lat, f, lev5, linewidth=1.3, transform=ccrs.PlateCarree())
c5.clabel(fmt='%5.0f', fontsize=9)
こうなります.まさに妥協案,と言った感じです..
lev1nのリスト内包表記は誰かの記事を参考にさせていただいたのですが,思い出したら書き加えます.
やり方は他にもあると思いますが,とにかくこの処理を加えないとラベルの裏に狭い方のコンターが描画され読みづらくなります.
参考になれば幸いです.