0

摘要版本: 我有 2 个使用 holoviewsstreams.Selection1DDynamicMap. 当单独绘制时,它们可以设置不同的缩放级别(第二个图是第一个图的放大版本)。但是,当我在布局中并排绘制它们时,我无法在每个图上设置独立的缩放级别。如何生成一个布局,其中两个包含的地图处于不同的缩放级别但它们仍然共享它们的轴?

通过进一步调查,此问题似乎适用于全息视图布局和面板行、列和网格规范。本质上,当我使用其中一种机制来呈现我的两个绘图时,我在绘图级别设置的任何选项都会被布局、行等覆盖。

完整版: 我有 2 个合唱团:

1. 英国地图。多边形是地方当局区。引脚是商店位置。

# LHS UK MAP: 3 components - the map, the store pins and the map tile
uk_map = gv.Polygons(all_lads, vdims=["store_lad_name","store_sales_count","store_lad_sales_rank"]
           ).opts(padding=(0,0.2),color="store_lad_sales_rank",
                  cmap = "Reds_r", colorbar=True,
                  hover_line_color="black", hover_alpha=0.2, 
                  line_width = 1,show_legend=True,
                  legend_position="top", clabel="Sales League",
                  width=850, height=1000
                 )

uk_store_pins = gv.Points(all_uk_stores[["store_long","store_lat","store_name","store_sales_league", 
                                         "store_sales_count","avg_cust_dist_trav_miles","store_postcode",
                                         "store_lad_name"]],
                 label = "All UK Store Locations").opts(tools=["hover","tap"],
                                                        color="purple",size = 10,
                                                        line_color="black",hover_color="orange",
                                                        hover_line_color="white",line_width=2,
                                                        legend_position="top",muted_fill_alpha=0) 
uk_store_pins

lhs_map = uk_map * uk_store_pins * gvts.OSM
lhs_map 

在此处输入图像描述

当您单击特定的商店位置图钉时,它应该会生成此地图的附加放大版本:

2.商店特定的放大地图:

# ZOOMED IN PLOT HAS THE FOLLOWING COMPONENTS - the zoomed in map, the pin, the radius and the map tile
def produce_zoomed_in_maps(index):
    
    # DRAW THE ZOOMED IN MAP, BASED ON THE map_selection
    zoom_map = gv.Polygons(map_selection, vdims=["LAD20NM"]
               ).opts(tools=["hover","tap"],
                      padding=(0,0.2), toolbar="below", cmap = "Blues", 
                      hover_line_color="red", hover_alpha=0.2, line_width = 1,
                      width=850, height=1000
                     )
    
    # SPECIFIC PIN FOR THE STORE THAT THIS ZOOMED IN MAP RELATES TO - THIS IS A SOURCE OF MAP DATA ON HOVER
    selected_store = store.index
    store_pin = gv.Points(all_uk_stores.iloc[selected_store][["store_long","store_lat","store_name",
                                                              "store_sales_league", "store_sales_count",
                                                              "avg_cust_dist_trav_miles","store_postcode",
                                                              "store_lad_name"]],
                 label = "Store Location").opts(tools=["hover","tap"],
                                                color="purple",size = 15,
                                                line_color="black",hover_color="orange",
                                                hover_line_color="white",line_width=2,
                                                legend_position="top"
                                               ) 
    
    map_result_pre = zoom_map * store_pin * gvts.OSM
    return map_result_pre
# CALCULATE radius
# THIS IS ADAPTED FROM: https://gis.stackexchange.com/questions/289044/creating-buffer-circle-x-kilometers-from-point-using-python

proj_wgs84 = pyproj.Proj('+proj=longlat +datum=WGS84')

def geodesic_point_buffer(index):
    lat = all_uk_stores.iloc[index]["store_lat"]
    lon = all_uk_stores.iloc[index]["store_long"]
    km = all_uk_stores.iloc[index]["avg_cust_dist_trav_km"]
    # Azimuthal equidistant projection
    aeqd_proj = '+proj=aeqd +lat_0={lat} +lon_0={lon} +x_0=0 +y_0=0'
    project = partial(
        pyproj.transform,
        pyproj.Proj(aeqd_proj.format(lat=lat, lon=lon)),
        proj_wgs84)
    buf = Point(0, 0).buffer(km * 1000)  # distance in metres
    cust_radius_coords = transform(project, buf).exterior.coords[:]
    # THIS WILL RETURN THE SET OF POINTS (LONG&LAT) THAT TOGETHER MAKE UP THE RADIUS AROUND EACH STORE
    radius = gv.Points(cust_radius_coords)
    return radius
# PRODUCE THE COMBINED PLOT:
def map_it_FINAL(index):
    return produce_zoomed_in_maps(index[0]) * geodesic_point_buffer(index[0])

在此处输入图像描述

当我分别绘制 2 个等值线时,它们具有上述所需的缩放级别。

但是,如果我将两个图链接在一起并使用布局并排显示两个地图(左侧为完整的英国地图,右侧放大了商店特定地图),则右侧放大的图实际上并没有缩放。相反,它与完整的英国地图保持在相同的缩放级别(抱歉,在这里我不得不显示一个在另一个之上而不是从左到右的图):

# LINK TOGETHER LHS AND RHS PLOT
selection = streams.Selection1D(source=uk_store_pins,index=[0])

# CREATE A DYNAMIC MAP, FEED IN YOUR FUNCTION NAME AND THE VARIABLE SET FOR THE SELECTION STREAM IE "selection"
rhs_related_zoomed_map = hv.DynamicMap(map_it_FINAL,streams=[selection])
# PRODUCE YOUR SIDE BY SIDE PLOTS
lhs_map + rhs_related_zoomed_map

在此处输入图像描述在此处输入图像描述

我尝试按照此处所述手动设置正确地图的缩放:https ://github.com/holoviz/geoviews/issues/340

def set_zoom_level(index):
    store = all_uk_stores.iloc[index[0]]
    store_catchment_lads = store["catchment_lads"].tolist()
    map_selection = lad20_shpfile.loc[lad20_shpfile["LAD20NM"].isin(store_catchment_lads)]
    minx,miny,maxx,maxy = map_selection["geometry"].total_bounds
    return minx,miny,maxx,maxy

minx,miny,maxx,maxy = set_zoom_level(selection.index)
lhs_map + rhs_related_zoomed_map.redim.range(Longitude=(minx, maxx), Latitude=(miny, maxy))

这成功地将我的右侧地图的缩放设置为所需的级别,但不幸的是它也将整个英国地图放大了相同的数量。

在此处输入图像描述在此处输入图像描述

我还尝试为两个图设置缩放级别(使用英国的 total_bounds 左图),但这只会产生与不为任一图设置缩放级别相同的结果。

我还尝试shared_axes=False在布局上进行设置。这具有为我的左右等值线具有两个单独的缩放级别的理想结果。但是,现在由于轴不再链接,虽然单击英国地图确实会在右侧生成正确的放大地图,但右侧地图不会移动到每个引脚选择的新位置。您必须手动平移到新位置。

如何生成全息视图布局或面板行、列或网格规范,其中两个包含的地图处于不同的缩放级别但它们仍然共享它们的轴?

谢谢

4

1 回答 1

1

好问题!据我所知,轴共享的唯一预建选项要么完全打开,要么完全关闭,因此您必须自己制作。可能有更好的方法,但在这种情况下,我要做的是按照http://holoviews.org/user_guide/Custom_Interactivity.html连接第一张地图上的 Tap 源以设置另一张地图的范围。我没试过,但似乎可行...

于 2020-09-23T17:37:25.337 回答