Beispiel #1
0
class BasemapTool:
    """Widget for switching between different basemaps (TileLayers).
    
    This will not work in combination with `ipyleaflet.SplitMapControl`.
    """
    def __init__(self,
                 description: str = "Basemap",
                 position: str = "topright",
                 a_map: Map = None):
        options = list(yield_basemap_dicts())
        options = [opt["name"] for opt in options]

        current_basemap_name = [
            l for l in a_map.layers if type(l) == TileLayer
        ][0].name
        start_value = current_basemap_name if current_basemap_name in options else options[
            0]

        dropdown = Dropdown(description=description,
                            options=options,
                            value=start_value,
                            layout=Layout(width="250px"))

        close_btn = Button(
            icon="times",
            button_style="info",
            tooltip="Close the basemap widget",
            layout=Layout(width="32px"),
        )

        self.widget = HBox([dropdown, close_btn])

        def switch(basemap_name):
            if len(a_map.layers) == 1:
                a_map.layers = tuple([TileLayer(**get_basemap(basemap_name))])
            else:
                old_basemap = [
                    l for l in a_map.layers if type(l) == TileLayer
                ][0]
                a_map.substitute_layer(old_basemap,
                                       TileLayer(**get_basemap(basemap_name)))

        def on_click(change):
            basemap_name = change["new"]
            switch(basemap_name)

        dropdown.observe(on_click, "value")

        def close_click(change):
            if a_map.basemap_ctrl is not None and a_map.basemap_ctrl in a_map.controls:
                a_map.remove_control(a_map.basemap_ctrl)
            self.widget.close()

        close_btn.on_click(close_click)

        self.widget_control = WidgetControl(widget=self.widget,
                                            position="topright")
        a_map.add_control(self.widget_control)
        a_map.basemap_ctrl = self.widget_control
        switch(dropdown.value)
Beispiel #2
0
class NBProgressBar(ProgressBar):
    def __init__(self,
                 gen,
                 total=None,
                 display=True,
                 leave=True,
                 parent=None,
                 auto_update=True):
        self.progress, self.text = IntProgress(
            min=0, max=len(gen) if total is None else total), HTML()
        self.box = HBox([self.progress, self.text])
        super().__init__(gen, total, display, leave, parent, auto_update)

    def on_iter_begin(self):
        if self.display: display(self.box)
        self.is_active = True

    def on_interrupt(self):
        self.progress.bar_style = 'danger'
        self.is_active = False

    def on_iter_end(self):
        if not self.leave: self.box.close()
        self.is_active = False

    def on_update(self, val, text):
        self.text.value = text
        self.progress.value = val
Beispiel #3
0
class ProgressIPy(ProgressBase):  # pragma: no cover
    HTMLBOX = '<div class="widget-hbox widget-progress"><div class="widget-label" style="display:block;">{0}</div></div>'

    def __init__(self, *args, **kargs):

        # Ipython gives warnings when using widgets about the API potentially changing
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            try:
                from ipywidgets import HTML, HBox, IntProgress
            except ImportError:  # Support IPython < 4.0
                from IPython.html.widgets import HTML, HBox, IntProgress

        super().__init__(*args, **kargs)
        self.prog = IntProgress(max=self.length)
        self._label = HTML()
        self._box = HBox((self.prog, self._label))

    def start(self):
        from IPython.display import display

        display(self._box)
        super().start()

    @property
    def value(self):
        """This is the current value, -1 allowed (automatically fixed for display)"""
        return self._value

    @value.setter
    def value(self, val):
        self._value = val
        self.prog.value = max(val, 0)
        self.prog.description = f"{self.value / self.length:.2%}"
        if self.timer and val > 0:
            self._label.value = self.HTMLBOX.format(self.str_time_remaining())

    def display(self):
        pass

    def done(self):
        if self.clear:
            self._box.close()
Beispiel #4
0
class ProgressIPy(ProgressBase):  # pragma: no cover
    HTMLBOX = '<div class="widget-hbox widget-progress"><div class="widget-label" style="display:block;">{0}</div></div>'

    def __init__(self, *args, **kargs):

        # Ipython gives warnings when using widgets about the API potentially changing
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            try:
                from ipywidgets import IntProgress, HTML, HBox  # type: ignore
            except ImportError:  # Support IPython < 4.0
                from IPython.html.widgets import IntProgress, HTML, HBox  # type: ignore

        super(ProgressIPy, self).__init__(*args, **kargs)
        self.prog = IntProgress(max=self.length)
        self._label = HTML()
        self._box = HBox((self.prog, self._label))

    def start(self):
        from IPython.display import display  # type: ignore
        display(self._box)
        super(ProgressIPy, self).start()

    @property
    def value(self):
        """This is the current value, -1 allowed (automatically fixed for display)"""
        return self._value

    @value.setter
    def value(self, val):
        self._value = val
        self.prog.value = max(val, 0)
        self.prog.description = "{0:.2%}".format(self.value / self.length)
        if self.timer and val > 0:
            self._label.value = self.HTMLBOX.format(self.str_time_remaining())

    def display(self):
        pass

    def done(self):
        if self.clear:
            self._box.close()
class Grid(object):
    ''' The class automatically closes Datagrid when reloaded
    and additionally display the Datagrid in a box. '''
    
    def __init__(self):
        # Initialize the chart with default ticker
        self.data_grid = DataGrid(data=[], layout=Layout(display='none',  flex='1'))
        self.box = HBox([self.data_grid])
        
    def close(self):
        self.data_grid.close()
        self.box.close()
    
    def show(self):
        return self.box
    
    def populate_data(self, data):
        self.close()
        self.data_grid = DataGrid(data=data, layout=Layout(height='500px', flex='1'))
        self.box = HBox([self.data_grid])
class VerboseOptimization(object):
    def __init__(self, model, opt, maxiters, verbose=False, current_iteration=0, ipython_notebook=True, clear_after_finish=False):
        self.verbose = verbose
        if self.verbose:
            self.model = model
            self.iteration = current_iteration
            self.p_iter = self.iteration
            self.maxiters = maxiters
            self.len_maxiters = len(str(int(maxiters)))
            self.opt_name = opt.opt_name
            self.opt = opt
            self.model.add_observer(self, self.print_status)
            self.status = 'running'
            self.clear = clear_after_finish

            self.update()

            try:  # pragma: no cover
                from IPython.display import display
                from ipywidgets import IntProgress, HTML, Box, VBox, HBox
                self.text = HTML(width='100%')
                self.progress = IntProgress(min=0, max=maxiters)
                #self.progresstext = Text(width='100%', disabled=True, value='0/{}'.format(maxiters))
                self.model_show = HTML()
                self.ipython_notebook = ipython_notebook
                get_ipython
            except:
                # Not in Ipython notebook
                self.ipython_notebook = False

            if self.ipython_notebook:  # pragma: no cover
                left_col = VBox(
                    children=[self.progress, self.text], padding=2, width='40%')
                right_col = Box(
                    children=[self.model_show], padding=2, width='60%')
                self.hor_align = HBox(
                    children=[left_col, right_col], width='100%', orientation='horizontal')

                display(self.hor_align)

                try:
                    self.text.set_css('width', '100%')
                    left_col.set_css({
                        'padding': '2px',
                        'width': "100%",
                    })

                    right_col.set_css({
                        'padding': '2px',
                    })

                    self.hor_align.set_css({
                        'width': "100%",
                    })

                    self.hor_align.remove_class('vbox')
                    self.hor_align.add_class('hbox')

                    left_col.add_class("box-flex1")
                    right_col.add_class('box-flex0')

                except:
                    pass

                # self.text.add_class('box-flex2')
                # self.progress.add_class('box-flex1')
            else:
                self.exps = exponents(self.fnow, self.current_gradient)
                print('Running {} Code:'.format(self.opt_name))
                print('  {3:7s}   {0:{mi}s}   {1:11s}    {2:11s}'.format(
                    "i", "f", "|g|", "runtime", mi=self.len_maxiters))

    def __enter__(self):
        self.start = time.time()
        self._time = self.start
        return self

    def print_out(self, seconds):
        if seconds < 60:
            ms = (seconds % 1)*100
            self.timestring = "{s:0>2d}s{ms:0>2d}".format(
                s=int(seconds), ms=int(ms))
        else:
            m, s = divmod(seconds, 60)
            if m > 59:
                h, m = divmod(m, 60)
                if h > 23:
                    d, h = divmod(h, 24)
                    self.timestring = '{d:0>2d}d{h:0>2d}h{m:0>2d}'.format(
                        m=int(m), h=int(h), d=int(d))
                else:
                    self.timestring = '{h:0>2d}h{m:0>2d}m{s:0>2d}'.format(
                        m=int(m), s=int(s), h=int(h))
            else:
                ms = (seconds % 1)*100
                self.timestring = '{m:0>2d}m{s:0>2d}s{ms:0>2d}'.format(
                    m=int(m), s=int(s), ms=int(ms))
        if self.ipython_notebook:  # pragma: no cover
            names_vals = [['optimizer', "{:s}".format(self.opt_name)],
                          ['runtime', "{:>s}".format(self.timestring)],
                          ['evaluation', "{:>0{l}}".format(
                              self.iteration, l=self.len_maxiters)],
                          ['objective', "{: > 12.3E}".format(self.fnow)],
                          ['||gradient||',
                              "{: >+12.3E}".format(float(self.current_gradient))],
                          ['status', "{:s}".format(self.status)],
                          ]
            #message = "Lik:{:5.3E} Grad:{:5.3E} Lik:{:5.3E} Len:{!s}".format(float(m.log_likelihood()), np.einsum('i,i->', grads, grads), float(m.likelihood.variance), " ".join(["{:3.2E}".format(l) for l in m.kern.lengthscale.values]))
            html_begin = """<style type="text/css">
    .tg-opt  {font-family:"Courier New", Courier, monospace !important;padding:2px 3px;word-break:normal;border-collapse:collapse;border-spacing:0;border-color:#DCDCDC;margin:0px auto;width:100%;}
    .tg-opt td{font-family:"Courier New", Courier, monospace !important;font-weight:bold;color:#444;background-color:#F7FDFA;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#DCDCDC;}
    .tg-opt th{font-family:"Courier New", Courier, monospace !important;font-weight:normal;color:#fff;background-color:#26ADE4;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#DCDCDC;}
    .tg-opt .tg-left{font-family:"Courier New", Courier, monospace !important;font-weight:normal;text-align:left;}
    .tg-opt .tg-right{font-family:"Courier New", Courier, monospace !important;font-weight:normal;text-align:right;}
    </style>
    <table class="tg-opt">"""
            html_end = "</table>"
            html_body = ""
            for name, val in names_vals:
                html_body += "<tr>"
                html_body += "<td class='tg-left'>{}</td>".format(name)
                html_body += "<td class='tg-right'>{}</td>".format(val)
                html_body += "</tr>"
            self.text.value = html_begin + html_body + html_end
            self.progress.value = (self.iteration+1)
            #self.progresstext.value = '0/{}'.format((self.iteration+1))
            self.model_show.value = self.model._repr_html_()
        else:
            n_exps = exponents(self.fnow, self.current_gradient)
            if self.iteration - self.p_iter >= 20 * np.random.rand():
                a = self.iteration >= self.p_iter * 2.78
                b = np.any(n_exps < self.exps)
                if a or b:
                    self.p_iter = self.iteration
                    print('')
                if b:
                    self.exps = n_exps
            print('\r', end=' ')
            print('{3:}  {0:>0{mi}g}  {1:> 12e}  {2:> 12e}'.format(self.iteration, float(self.fnow), float(self.current_gradient), "{:>8s}".format(
                self.timestring), mi=self.len_maxiters), end=' ')  # print 'Iteration:', iteration, ' Objective:', fnow, '  Scale:', beta, '\r',
            sys.stdout.flush()

    def print_status(self, me, which=None):
        self.update()

        t = time.time()
        seconds = t-self.start
        #sys.stdout.write(" "*len(self.message))
        if t-self._time > 1. or seconds < .2:
            self.print_out(seconds)
            self._time = t

        self.iteration += 1

    def update(self):
        self.fnow = self.model.objective_function()
        if self.model.obj_grads is not None:
            grad = self.model.obj_grads
            self.current_gradient = np.dot(grad, grad)
        else:
            self.current_gradient = np.nan

    def finish(self, opt):  # pragma: no cover
        import warnings
        warnings.warn('Finish now automatic, deprecating', DeprecationWarning)

    def __exit__(self, type, value, traceback):
        if self.verbose:
            self.status = self.opt.status

            self.stop = time.time()
            self.model.remove_observer(self)
            self.print_out(self.stop - self.start)

            if not self.ipython_notebook:
                print()
                print('Runtime: {}'.format("{:>9s}".format(self.timestring)))
                print('Optimization status: {0}'.format(self.status))
                print()
            elif self.clear:  # pragma: no cover
                self.hor_align.close()
            else:  # pragma: no cover
                if 'conv' in self.status.lower():
                    self.progress.bar_style = 'success'
                elif self.iteration >= self.maxiters:
                    self.progress.bar_style = 'warning'
                else:
                    self.progress.bar_style = 'danger'
Beispiel #7
0
class TileGridTool:
    """A tool for adding a dynamic Mercator tile grid to a map.

    The grid is recalculated/adapted dynamically to the visible part of the map
    only as the user zooms and pans over it. The grid level is limited from 0
    to the current map zoom level plus 4, or there would be too many cells and
    the grid would be too dense to see anything else.
    """
    def __init__(
        self,
        a_map: Map,
        description: str = "Mercator",
        position: str = "topright",
    ):
        """Instantiate a tile grid tool and place it on a map.
        """
        self._max_zoom_delta = 4

        self.tile_id = ""
        self.level = int(a_map.zoom)
        style = {"color": "#888888", "weight": 1, "fillOpacity": 0}
        hover_style = {"weight": 3, "fillOpacity": 0.1}
        self.gj = GeoJSON(data=geojson.Feature(),
                          name=description,
                          style=style,
                          hover_style=hover_style)

        min, max = 0, int(a_map.zoom) + self._max_zoom_delta
        self.slider = IntSlider(description=description,
                                min=min,
                                max=max,
                                value=self.level)
        self.ht = HTML(f"ID: {self.tile_id} Map zoom: {int(a_map.zoom)}")
        self.close_btn = Button(
            icon="times",
            button_style="info",
            tooltip="Close the widget",
            layout=Layout(width="32px"),
        )
        self.widget = HBox([self.slider, self.ht, self.close_btn])

        def hover(event, feature, **kwargs):
            if event == "mouseover":
                self.tile_id = feature["id"]
                self.ht.value = f"{self.tile_id} Map zoom: {int(a_map.zoom)}"

        def slider_moved(event):
            if event["type"] == "change" and event["name"] == "value":
                self.level = event["new"]

                # Ipyleaflet buglet(?): This name is updated in the GeoJSON layer,
                # but not in the LayersControl!
                self.gj.name = f"Mercator"  # level {self.level}"

                self.tile_id = ""
                map_interacted({
                    "type": "change",
                    "name": "bounds",
                    "owner": a_map
                })

        self.slider.observe(slider_moved)

        def map_interacted(event):
            if event["type"] == "change" and event["name"] == "bounds":
                self.ht.value = f"{self.tile_id}, Map zoom: {int(a_map.zoom)}"
                self.slider.max = int(a_map.zoom) + self._max_zoom_delta

                m = event["owner"]
                ((south, west), (north, east)) = m.bounds

                b_poly = list(m.bounds_polygon)
                b_poly += [tuple(b_poly[0])]
                # m += Polyline(locations=b_poly)

                # Attention in the order of west, south, east, north!
                tiles = mercantile.tiles(west,
                                         south,
                                         east,
                                         north,
                                         zooms=self.level)

                features = [mercantile.feature(t) for t in tiles]
                self.gj.data = geojson.FeatureCollection(features=features)

                # Ipyleaflet buglet(?): This name is updated in the GeoJSON layer,
                # but not in the LayersControl!
                self.gj.name = f"Mercator"  # level {self.level}"

                self.gj.on_hover(hover)

        def close_click(change):
            self.widget.children = []
            self.widget.close()

        self.close_btn.on_click(close_click)

        a_map += self.gj
        a_map.observe(map_interacted)
        map_interacted({"type": "change", "name": "bounds", "owner": a_map})

        self.widget_control = WidgetControl(widget=self.widget,
                                            position=position)
        a_map.add_control(self.widget_control)