简体   繁体   English

底图,投影='地理',控制mark_inset()位置

[英]Basemap, projection='geos', controlling mark_inset() location

I'm trying to make a plot using basemap with an inset zoom. 我正在尝试使用带有插入缩放的底图制作绘图。 I'm having trouble with the inset box from mark_inset() to appear anywhere besides the lower left hand corner. 我在使用mark_inset()的插入框时遇到问题,出现在左下角的任何地方。 It works for projection='cyl' but not for projection='geos' which is what I want. 它适用于projection ='cyl'但不适用于projection ='geos'这就是我想要的。

from mpl_toolkits.basemap import Basemap 
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

map1 = Basemap(projection='geos', lat_0=0, lon_0=0)
map1.drawmapboundary()
map1.drawcoastlines()

axins = zoomed_inset_axes(ax, 7, loc=3)
axins.set_xlim(-12, 5)
axins.set_ylim(50, 60)

map2 = Basemap(projection='geos', lon_0=0, llcrnrlon=-12, llcrnrlat=50, urcrnrlon=5, urcrnrlat=60[enter image description here][1])
map2.drawcoastlines()

mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") 

Bumping this...can confirm it's an issue. 碰到这个......可以证实这是一个问题。

I haven't tried every projection, but of the dozen I have tried, 'cyl' is the only one where mark_inset works. 我没有尝试过每一个投影,但在我尝试过的十几个投影中,'cyl'是唯一一个mark_inset工作的投影。 All others locate it at lower left. 所有其他人都在左下方找到它。

I encountered the same problem. 我遇到了同样的问题。 This is because Basemap works internally with projected coordinates - except for the cyl projection; 这是因为Basemap在内部使用投影坐标 - 除了cyl投影; read here : 在这里阅读:

Calling a Basemap class instance with the arguments lon, lat will convert lon/lat (in degrees) to x/y map projection coordinates (in meters). 使用参数lon调用Basemap类实例,lat将lon / lat(以度为单位)转换为x / y地图投影坐标(以米为单位)。 [...] [...]

For cylindrical equidistant projection (cyl), this does nothing (ie x,y == lon,lat). 对于圆柱等距投影(cyl),这没有任何作用(即x,y == lon,lat)。

To make the marking work properly, you need to first extract the inset map limits, convert them to geographic coordinates, and finally re-project them again onto the main map. 要使标记正常工作,您需要首先提取插入地图限制,将它们转换为地理坐标,然后再将它们重新投影到主地图上。

I wrote a small replacement function for mark_inset that additionally needs the Basemap objects m & m2 of both maps (main and inset): 我为mark_inset写了一个小的替换函数,另外需要两个map(main和inset)的底图对象mm2

def mark_inset(ax, ax2, m, m2, loc1=(1, 2), loc2=(3, 4), **kwargs):
    """
    Patched mark_inset to work with Basemap.
    Reason: Basemap converts Geographic (lon/lat) to Map Projection (x/y) coordinates

    Additionally: set connector locations separately for both axes:
        loc1 & loc2: tuple defining start and end-locations of connector 1 & 2
    """

    # Doesn't work for Basemap
#    rect = TransformedBbox(inset_axes.viewLim, parent_axes.transData)

#    axzoom_geoLims = np.array(m2(*ax2.viewLim._points.T, inverse=True))
    axzoom_geoLims = m2(ax2.get_xlim(), ax2.get_ylim(), inverse=True)
    rect = TransformedBbox(Bbox(np.array(m(*axzoom_geoLims)).T), ax.transData)

    pp = BboxPatch(rect, fill=False, **kwargs)
    ax.add_patch(pp)

    p1 = BboxConnector(ax2.bbox, rect, loc1=loc1[0], loc2=loc1[1], **kwargs)
    ax2.add_patch(p1)
    p1.set_clip_on(False)
    p2 = BboxConnector(ax2.bbox, rect, loc1=loc2[0], loc2=loc2[1], **kwargs)
    ax2.add_patch(p2)
    p2.set_clip_on(False)

    return pp, p1, p2

Note: the function is based on another answer that allows to set different start and end locations for the connectors. 注意:该功能基于另一个答案 ,允许为连接器设置不同的开始和结束位置。 Hence, you can do that with this function as well. 因此,您也可以使用此功能。

Note2: the ax2 object doesn't need to be necessarily an inset object - it can be any axis object (eg, also a subplot). 注意2: ax2对象不一定是插入对象 - 它可以是任何轴对象(例如,也是子图)。 Therefore, a better name for the function would be mark_geo_zoom . 因此,函数的更好名称是mark_geo_zoom ;-) ;-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM