【问题标题】:Placing subplot at lat/long co-ordinates in cartopy将子图放置在 cartopy 中的纬度/经度坐标处
【发布时间】:2017-01-18 10:10:52
【问题描述】:

我正在尝试将 matplotlib 轴放置在 cartopy 图上的特定坐标处,但不知道如何正确设置位置。代码应该:

  • 绘制德国的正投影
  • 在柏林的位置添加文字“柏林”
  • 在柏林的位置添加直方图

我的代码如下:

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature

plt.figure(figsize=(8, 8))

extent = [6, 15, 47, 55]          # Extent of Germany in Lat/Long

lat, lon = 52.520007, 13.404954   # Location of Berlin

# Plot our coastline and set the extent
ax = plt.axes(projection=ccrs.Orthographic(central_longitude=10.5, \
         central_latitude=51.0, \
         globe=None))
ax.coastlines('10m')
ax.set_extent(extent)

# Add text at the location of Berlin
plt.text(lon, lat, 'Berlin', \
         verticalalignment='center', \
         horizontalalignment='right', \
         transform=ccrs.PlateCarree())

# Add subplot
sub_ax = plt.axes([(lon-extent[0])/(extent[1] - extent[0]), \
                   (lat-extent[2])/(extent[3] - extent[2]), \
                   .1, .1], \
                   axisbg='none')

plt.hist(np.random.randn(100), 10, normed=1)

如您所见,直方图不在柏林,因为(我认为)它与图形的边界框相关,而不是轴。我已经尝试像添加 plt.text 一样添加 transform=ax.transAxes,但这会在 BboxTransformTo 上产生 unhashable type 错误。

我应该补充一点,我知道我的位置计算通常不起作用,因为我没有使用欧几里得几何,但就我的目的而言,它已经足够接近了。

【问题讨论】:

    标签: python matplotlib cartopy


    【解决方案1】:

    下面的代码应该得到所需的相对于图形边缘的位置:

    ax_lon = (lon-extent[0])/(extent[1] - extent[0])
    ax_lat = (lat-extent[2])/(extent[3] - extent[2])
    fig_lon = (ax.bbox.x0 + ax_lon * ax.bbox.width) / fig.bbox.width
    fig_lat = (ax.bbox.y0 + ax_lat * ax.bbox.height) / fig.bbox.height
    

    但如果调整图形大小,这些值就会出错。我能想到的在调整大小时将其保持在正确位置的唯一方法是使用事件回调来更新位置。

    【讨论】:

    • 迟到的谢谢!我仍然在努力让它工作(尽管得到无花果的 bbox 非常有用),我意识到我使用 jupyter 笔记本有点搞砸了。笔记本正在调整图形的大小(所以figsize=(8,8) 实际上的意思是“8 高,但只有你需要的宽度”。结果是我根本没有考虑调整大小;当我在 IPython 中尝试时按照您的描述工作,但仅在调整大小之前。
    【解决方案2】:

    这是我的尝试:

    import numpy as np
    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    #import cartopy.feature as cfeature
    from mpl_toolkits.axes_grid1.inset_locator import inset_axes
    
    height = 18.
    width = 8.
    plt.figure(figsize = (width, height))
    
    extent = [6, 15, 47, 55]  # Extent of Germany [Long1,2, Lat1,2]
    
    ortho = ccrs.Orthographic(central_longitude=10.5, \
             central_latitude=51.0, \
             globe=None)
    
    ax = plt.axes(projection=ortho)
    ax.coastlines('50m')
    ax.set_extent(extent)
    
    def plot_city_name(lon, lat, cityname):
        """plot city name at specified location"""
        plt.text(lon, lat, cityname, \
                 va='center', \
                 fontsize=18, \
                 ha='right', \
                 transform=ccrs.PlateCarree(), \
                 zorder=0)
    
    lat, lon = 52.520007, 13.404954    # Location of Berlin
    plot_city_name(lon, lat, 'Berlin')
    
    latd, lond = 51.341734, 7.417392   # Location of Hagen
    plot_city_name(lond, latd, 'Hagen')
    
    def plot_hist(mapx, mapy, ax, width):
        """plot simple histogram at specified location"""
        ax_sub= inset_axes(ax, width=width, \
                           height=width, loc=3, \
                           bbox_to_anchor=(mapx, mapy), \
                           bbox_transform=ax.transData, \
                           borderpad=0)
        # plot simple histogram
        ax_sub.hist(np.random.randn(100), bins=10, normed=1)
    
    def xy_from_longlat(lon, lat):
        """convert long-lat (degrees) to grid values""" 
        return ortho.transform_point(lon, lat, ccrs.PlateCarree())
    
    # plot histograms at 2 locations
    inset_size = 1.0  # unit?
    
    mapx, mapy = xy_from_longlat(lon, lat)
    plot_hist(mapx, mapy, ax, inset_size)   # Berlin
    
    mapx, mapy = xy_from_longlat(lond, latd)
    plot_hist(mapx, mapy, ax, inset_size)   # Hagen
    
    plt.show()
    

    输出:

    编辑

    在 ipython/jupyter notebook 上,您可以平移和缩放图形,而不会破坏直方图的相对位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多