python - 使用小部件更新 Gmaps + Jupyter 中的标记

标签 python python-3.x jupyter-notebook

我正在研究 gmaps,我正在尝试使用 widgets.button 刷新 gmap 标记,但是当我单击按钮时无法刷新 map 。 也许是一个简单的问题,但我试了几个小时却无法解决。 遵循我的代码。

from IPython.display import display
import ipywidgets as widgets

import gmaps
gmaps.configure(api_key='')


class AcledExplorer(object):
    """
    Jupyter widget for exploring the ACLED dataset.

    The user uses the slider to choose a year. This renders
    a heatmap of civilian victims in that year.
    """

    def __init__(self):
        self.marker_locations = [(None, None)]
        self._slider = None
        self._slider2 = None
        title_widget = widgets.HTML(
            '<h3>MY TEST, my test</h3>'
            '<h4>test1 <a href="https://www.test.com/">ACLED project</a></h4>'
        )

        map_figure = self._render_map(-15.7934036, -47.8823172)
        control = self._render_control()
        self._container = widgets.VBox([title_widget, control, map_figure])

    def render(self):
        display(self._container)

    def on_button_clicked(self, b):
        latitude = self.FloatSlider1.value
        longitude = self.FloatSlider2.value
        print("Button clicked.")
        self.markers = gmaps.marker_layer([(latitude, longitude)])
        return self._container

    def _render_control(self):

        """ Render the widgets """

        self.FloatSlider1 = widgets.FloatSlider(
        value=-15.8,
        min=-34,
        max=4.5,
        step=0.2,
        description='Latitude:',
        disabled=False,
        continuous_update=False,
        orientation='horizontal',
        readout=True,
        readout_format='.1f',
    )
        self.FloatSlider2 = widgets.FloatSlider(
        value=-47.9,
        min=-74,
        max=-33,
        step=0.2,
        description='Longitude:',
        disabled=False,
        continuous_update=False,
        orientation='horizontal',
        readout=True,
        readout_format='.1f',
    )
        self.button = widgets.Button(
            description="Plot!"
        )

        self.button.on_click(self.on_button_clicked)

        controls = widgets.VBox(
        [self.FloatSlider1, self.FloatSlider2, self.button])
        return controls

    def _render_map(self, latitude, longitude):
        """ Render the initial map """
        self.marker_locations = [(latitude, longitude)]
        brasilia_coordinates = (-15.7934036, -47.8823172)

        fig = gmaps.figure(center=brasilia_coordinates, zoom_level=3)
        self.markers = gmaps.marker_layer(self.marker_locations)
        fig.add_layer(self.markers)
        return fig


AcledExplorer().render()

在将值从 slider 链接到按钮后,我开始创建小部件。单击按钮时我需要刷新标记位置。

在函数 on_button_click 中,我可以看到纬度和经度的新闻值是从 slider 获取的,所以我正在更新 self.marker,也许我的错误留在这里。

Result of code image

最佳答案

你的代码有问题

on_button_click 中,您实际上并没有更新标记层。你目前写:

self.markers = gmaps.marker_layer([(latitude, longitude)])

但这只是设置了您的类的 markers 属性。您真正想要做的是改变标记层中的标记集。您可以做的最简单的更改是将该行更改为:

self.markers.markers = [gmaps.Marker(location=(latitude, longitude))]

这会改变标记层的 markers 属性——基本上是标记列表。每次按下 plot 时,它都会破坏 map 上的标记,并在更新后的位置用新标记替换它。

改进您的解决方案

使用像 marker_layer 这样的高级工厂方法可以掩盖 jupyter-gmaps 如何在内部使用小部件。为了让它更容易理解,让我们介绍一个创建 gmaps.Marker 对象的 _create_marker() 方法:

def _create_marker(self, latitude, longitude):
    return gmaps.Marker(location=(latitude, longitude))

我们现在可以在初始渲染中使用它:

def _render_map(self, latitude, longitude):
    """ Render the initial map """
    brasilia_coordinates = (-15.7934036, -47.8823172)

    fig = gmaps.figure(center=brasilia_coordinates, zoom_level=3)
    self.marker_layer = gmaps.Markers()
    initial_marker = self._create_marker(latitude, longitude)
    self.marker_layer.markers = [initial_marker]  # set the first marker
    fig.add_layer(self.marker_layer)
    return fig

请注意,我已将 self.markers 重命名为 self.marker_layer 以表明它是一个层。

最后,现在是更新代码:

def on_button_clicked(self, _):
    latitude = self.FloatSlider1.value
    longitude = self.FloatSlider2.value

    # look how closely the following two lines match the construction code
    new_marker = self._create_marker(latitude, longitude)
    self.marker_layer.markers = [new_marker]

关于python - 使用小部件更新 Gmaps + Jupyter 中的标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54857781/

相关文章:

python - 如何在pycharm中相应选择python版本?

python - 如何使用opencv python将YUV_420_888转换为BGR?

python-3.x - 如何构建基于时间的 EWMA

python - 使用 IPython.display.image : sometimes work, 有时不显示来自网络的图像

python - 现在开始异步任务,稍后等待

python - 访问 Jinja2 中的宏上下文

python - 如何对 pandas 数据框进行子集化

python - Django 联系表邮件错误 :Address family not supported by protocol Request

python - 从字符串中删除数字,同时保留字母数字单词

python - 自动将 Jupyter notebook 的副本维护为纯 Python 代码