将子图放置在latopy中的lat / long坐标上

时间:2017-01-18 10:10:53

标签: python matplotlib cartopy

我正在尝试将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)

Code output

正如你所看到的,直方图不在柏林,因为(我认为)它是相对于图的边界框而不是轴。我已尝试像transform=ax.transAxes一样添加plt.text,但这会在unhashable type上出现BboxTransformTo错误。

我应该补充一点,我知道我的位置计算一般不起作用,因为我没有使用欧几里德几何,但为了我的目的,它足够接近。

2 个答案:

答案 0 :(得分:3)

以下代码应该获得相对于图边缘的所需位置:

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

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

答案 1 :(得分:1)

这是我的尝试:

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()

输出:

enter image description here

修改

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