Skip to content

Update DrawControl polygon properties dict #425

Open
@Dylan-Rich

Description

@Dylan-Rich

Is it currently possible to update the properties of the DrawControls polygon dict for each new polygon drawn? For some context I'm using on_draw to generate a matplotlib plot for each polygon drawn on my map. I iterate through the default matplotlib color iterator on each new draw. I've tried removing the draw control from the map, adjusting the polygon dict, then adding the control back to the map. This works initially but seems to trigger another on_draw event and causes the plotting operation to execute again. I've include a toy example (I'm using ipyleaflets version 0.11.1).

import ipyleaflet
import IPython

import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np

from ipyleaflet import DrawControl
class ToyMultiplot(object):
    def __init__(self, map_widget):
        self.m = map_widget
        
        self.color_iterator = plt.rcParams['axes.prop_cycle'].by_key()['color']
        self.color_index = 0
        
        self.ax = None
        self.fig = None
        
        self.draw_control = DrawControl()
        self.draw_control.polygon = {"shapeOptions": {
                    "fillColor": self.color_iterator[self.color_index],
                    "color": self.color_iterator[self.color_index],
                    "fillOpacity": 0.4
                    }}
        
        self.m.add_control(self.draw_control)
        
        self.fig_output = widgets.Output()
        self.fig_widget = ipyleaflet.WidgetControl(widget=self.fig_output, position='bottomright')
        self.m.add_control(self.fig_widget)
        
        self.draw_control.on_draw(self.update_plot)
        self.draw_control.on_draw(self.update_draw_control_color)
        
    def update_plot(self, *args, **kwargs):
        if self.ax is None or self.fig is None:
            fig, ax = plt.subplots(figsize=[5,4])
            ax.cla()
            ax.set_visible(True)
            self.fig = fig
            self.ax = ax
            first_draw = True
        else:
            first_draw = False
            
        self.ax.scatter(np.random.randint(100, size=10), np.random.randint(100, size=10), color=self.color_iterator[self.color_index])
            
        if not first_draw:
            with self.fig_output:
                IPython.display.clear_output()
                
        with self.fig_output:
            IPython.display.display(self.fig)
            
        if self.color_index >= len(self.color_iterator):
            self.color_index = 0
        
        self.color_index += 1
            
    def update_draw_control_color(self, *args, **kwargs):
        self.m.remove_control(self.draw_control)
        self.draw_control.polygon = {"shapeOptions": {
                        "fillColor": self.color_iterator[self.color_index],
                        "color": self.color_iterator[self.color_index],
                        "fillOpacity": 0.4
                        }}
        self.m.add_control(self.draw_control)
map_widget = ipyleaflet.Map()
plot_multi = ToyMultiplot(map_widget)
map_widget

multi_plot_polygon_issue

You can see that although there are only 4 color polygons on the map there are many more colors on the plot. Any thoughts or help here would be greatly appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions