Skip to content

plotlymap module

Canvas

The widgets.HBox containing the map and a toolbar.

Source code in leafmap/plotlymap.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class Canvas:
    """The widgets.HBox containing the map and a toolbar."""

    def __init__(
        self,
        map,
        map_min_width: Optional[str] = "90%",
        map_max_width: Optional[str] = "98%",
        map_refresh: Optional[bool] = False,
        **kwargs,
    ) -> None:
        """Initialize the Canvas.

        Args:
            map (go.FigureWidget): The map to display.
            map_min_width (str, optional): The minimum width of the map. Defaults to '90%'.
            map_max_width (str, optional): The maximum width of the map. Defaults to '98%'.
            map_refresh (bool, optional): Whether to refresh the map when the map is resized. Defaults to False.
        """
        from .toolbar import plotly_toolbar

        map_widget = widgets.Output(layout=widgets.Layout(width=map_max_width))
        with map_widget:
            display(map)

        self.map = map
        self.map_min_width = map_min_width
        self.map_max_width = map_max_width
        self.map_refresh = map_refresh
        self.map_widget = map_widget

        container_widget = widgets.VBox()
        self.container_widget = container_widget

        toolbar_widget = plotly_toolbar(self)
        sidebar_widget = widgets.VBox([toolbar_widget, container_widget])
        canvas = widgets.HBox([map_widget, sidebar_widget])

        self.canvas = canvas
        self.toolbar_widget = toolbar_widget

    def toolbar_reset(self):
        """Reset the toolbar so that no tool is selected."""
        if hasattr(self, "toolbar"):
            toolbar_grid = self.toolbar
            for tool in toolbar_grid.children:
                tool.value = False

__init__(map, map_min_width='90%', map_max_width='98%', map_refresh=False, **kwargs)

Initialize the Canvas.

Parameters:

Name Type Description Default
map FigureWidget

The map to display.

required
map_min_width str

The minimum width of the map. Defaults to '90%'.

'90%'
map_max_width str

The maximum width of the map. Defaults to '98%'.

'98%'
map_refresh bool

Whether to refresh the map when the map is resized. Defaults to False.

False
Source code in leafmap/plotlymap.py
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def __init__(
    self,
    map,
    map_min_width: Optional[str] = "90%",
    map_max_width: Optional[str] = "98%",
    map_refresh: Optional[bool] = False,
    **kwargs,
) -> None:
    """Initialize the Canvas.

    Args:
        map (go.FigureWidget): The map to display.
        map_min_width (str, optional): The minimum width of the map. Defaults to '90%'.
        map_max_width (str, optional): The maximum width of the map. Defaults to '98%'.
        map_refresh (bool, optional): Whether to refresh the map when the map is resized. Defaults to False.
    """
    from .toolbar import plotly_toolbar

    map_widget = widgets.Output(layout=widgets.Layout(width=map_max_width))
    with map_widget:
        display(map)

    self.map = map
    self.map_min_width = map_min_width
    self.map_max_width = map_max_width
    self.map_refresh = map_refresh
    self.map_widget = map_widget

    container_widget = widgets.VBox()
    self.container_widget = container_widget

    toolbar_widget = plotly_toolbar(self)
    sidebar_widget = widgets.VBox([toolbar_widget, container_widget])
    canvas = widgets.HBox([map_widget, sidebar_widget])

    self.canvas = canvas
    self.toolbar_widget = toolbar_widget

toolbar_reset()

Reset the toolbar so that no tool is selected.

Source code in leafmap/plotlymap.py
67
68
69
70
71
72
def toolbar_reset(self):
    """Reset the toolbar so that no tool is selected."""
    if hasattr(self, "toolbar"):
        toolbar_grid = self.toolbar
        for tool in toolbar_grid.children:
            tool.value = False

Map

Bases: FigureWidget

The Map class inherits the Plotly FigureWidget class. More info at https://plotly.com/python/figurewidget.

Source code in leafmap/plotlymap.py
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
class Map(go.FigureWidget):
    """The Map class inherits the Plotly FigureWidget class. More info at https://plotly.com/python/figurewidget."""

    def __init__(
        self,
        center: Optional[Tuple[float, float]] = (20, 0),
        zoom: Optional[float] = 1,
        basemap: Optional[str] = "open-street-map",
        height: Optional[int] = 600,
        **kwargs,
    ) -> None:
        """Initializes a map. More info at https://plotly.com/python/mapbox-layers/

        Args:
            center (tuple, optional): Center of the map. Defaults to (20, 0).
            zoom (float, optional): Zoom level of the map. Defaults to 1.
            basemap (str, optional): Can be one of string from "open-street-map", "carto-positron", "carto-darkmatter", "stamen-terrain", "stamen-toner" or "stamen-watercolor" . Defaults to 'open-street-map'.
            height (int, optional): Height of the map. Defaults to 600.
        """
        super().__init__(**kwargs)
        self.add_scattermapbox()
        self.update_layout(
            {
                "mapbox": {
                    "style": basemap,
                    "center": {"lat": center[0], "lon": center[1]},
                    "zoom": zoom,
                },
                "margin": {"r": 0, "t": 0, "l": 0, "b": 0},
                "height": height,
            }
        )

    def show(
        self,
        toolbar: Optional[bool] = True,
        map_min_width: Optional[str] = "91%",
        map_max_width: Optional[str] = "98%",
        refresh: Optional[bool] = False,
        **kwargs,
    ) -> None:
        """Shows the map.

        Args:
            toolbar (bool, optional): Whether to show the toolbar. Defaults to True.
            map_min_width (str, optional): The minimum width of the map. Defaults to '91%'.
            map_max_width (str, optional): The maximum width of the map. Defaults to '98%'.
            refresh (bool, optional): Whether to refresh the map when the map is resized. Defaults to False.

        Returns:
            Canvas: Map canvas.
        """
        if not toolbar:
            super().show(**kwargs)
        else:
            canvas = Canvas(
                self,
                map_min_width=map_min_width,
                map_max_width=map_max_width,
                map_refresh=refresh,
            )
            return canvas.canvas

    def clear_controls(self):
        """Removes all controls from the map."""
        config = {
            "scrollZoom": True,
            "displayModeBar": False,
            "editable": True,
            "showLink": False,
            "displaylogo": False,
        }
        self.show(toolbar=False, config=config)

    def add_controls(self, controls: List) -> None:
        """Adds controls to the map.

        Args:
            controls (list): List of controls to add, e.g., ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape'] See https://bit.ly/33Tmqxr
        """
        if isinstance(controls, str):
            controls = [controls]
        elif not isinstance(controls, list):
            raise ValueError(
                "Controls must be a string or a list of strings. See https://bit.ly/33Tmqxr"
            )

        self.update_layout(modebar_add=controls)

    def remove_controls(self, controls: List):
        """Removes controls to the map.

        Args:
            controls (list): List of controls to remove, e.g., ["zoomin", "zoomout", "toimage", "pan", "resetview"]. See https://bit.ly/3Jk7wkb
        """
        if isinstance(controls, str):
            controls = [controls]
        elif not isinstance(controls, list):
            raise ValueError(
                "Controls must be a string or a list of strings. See https://bit.ly/3Jk7wkb"
            )

        self.update_layout(modebar_remove=controls)

    def set_center(self, lat: float, lon: float, zoom: Optional[float] = None) -> None:
        """Sets the center of the map.

        Args:
            lat (float): Latitude.
            lon (float): Longitude.
            zoom (int, optional): Zoom level of the map. Defaults to None.
        """
        self.update_layout(
            mapbox=dict(
                center=dict(lat=lat, lon=lon),
                zoom=zoom if zoom is not None else self.layout.mapbox.zoom,
            )
        )

    def add_basemap(self, basemap: Optional[str] = "ROADMAP") -> None:
        """Adds a basemap to the map.

        Args:
            basemap (str, optional): Can be one of string from basemaps. Defaults to 'ROADMAP'.
        """
        if basemap not in basemaps:
            raise ValueError(
                f"Basemap {basemap} not found. Choose from {','.join(basemaps.keys())}"
            )

        if basemap in self.get_tile_layers():
            self.remove_basemap(basemap)
        layers = list(self.layout.mapbox.layers) + [basemaps[basemap]]
        self.update_layout(mapbox_layers=layers)

    def remove_basemap(self, name: str) -> None:
        """Removes a basemap from the map.

        Args:
            name (str): Name of the basemap to remove.
        """
        layers = list(self.layout.mapbox.layers)
        layers = [layer for layer in layers if layer["name"] != name]
        self.layout.mapbox.layers = layers

    def add_mapbox_layer(self, style: Union[str, Dict], access_token=None) -> None:
        """Adds a mapbox layer to the map.

        Args:
            layer (str | dict): Layer to add. Can be "basic", "streets", "outdoors", "light", "dark", "satellite", or "satellite-streets". See https://plotly.com/python/mapbox-layers/ and https://docs.mapbox.com/mapbox-gl-js/style-spec/
            access_token (str, optional): The Mapbox Access token. It can be set as an environment variable "MAPBOX_TOKEN". Defaults to None.
        """

        if access_token is None:
            access_token = os.environ.get("MAPBOX_TOKEN")

        self.update_layout(
            mapbox_style=style, mapbox_layers=[], mapbox_accesstoken=access_token
        )

    def add_layer(self, layer, name: Optional[str] = None, **kwargs):
        """Adds a layer to the map.

        Args:
            layer (plotly.graph_objects): Layer to add.
            name (str, optional): Name of the layer. Defaults to None.
        """
        if isinstance(name, str):
            layer.name = name
        self.add_trace(layer, **kwargs)

    def remove_layer(self, name: str) -> None:
        """Removes a layer from the map.

        Args:
            name (str): Name of the layer to remove.
        """
        if name in self.get_data_layers():
            self.data = [layer for layer in self.data if layer.name != name]
        elif name in self.get_tile_layers():
            self.layout.mapbox.layers = [
                layer for layer in self.layout.mapbox.layers if layer["name"] != name
            ]

    def clear_layers(self, clear_basemap: Optional[bool] = False):
        """Clears all layers from the map.

        Args:
            clear_basemap (bool, optional): If True, clears the basemap. Defaults to False.
        """
        if clear_basemap:
            self.data = []
        else:
            if len(self.data) > 1:
                self.data = self.data[:1]

    def get_layers(self) -> Dict:
        """Returns a dictionary of all layers in the map.
        Returns:
            dict: A dictionary of all layers in the map.
        """
        layers = {}

        for layer in self.layout.mapbox.layers:
            if layer["name"] is not None:
                layers[layer["name"]] = layer

        for layer in self.data:
            if layer.name is not None and layer.name != "trace 0":
                layers[layer.name] = layer

        return layers

    def get_tile_layers(self) -> Dict:
        """Returns a dictionary of tile layers in the map.

        Returns:
            dict: A dictionary of tile layers in the map.
        """

        layers = {}

        for layer in self.layout.mapbox.layers:
            if layer["name"] is not None:
                layers[layer["name"]] = layer

        return layers

    def get_data_layers(self) -> Dict:
        """Returns a dictionary of data layers in the map.

        Returns:
            dict: A dictionary of data layers in the map.
        """

        layers = {}

        for layer in self.data:
            if layer.name is not None and layer.name != "trace 0":
                layers[layer.name] = layer

        return layers

    def find_layer_index(self, name: str) -> int:
        """Finds the index of a layer.

        Args:
            name (str): Name of the layer to find.

        Returns:
            int: Index of the layer.
        """
        for i, layer in enumerate(self.data):
            if layer.name == name:
                return i

        for i, layer in enumerate(self.layout.mapbox.layers):
            if layer["name"] == name:
                return i

        return None

    def set_layer_visibility(self, name: str, show: Optional[bool] = True) -> None:
        """Sets the visibility of a layer.

        Args:
            name (str): Name of the layer to set.
            show (bool, optional): If True, shows the layer. Defaults to True.
        """

        if name in self.get_tile_layers():
            index = self.find_layer_index(name)
            self.layout.mapbox.layers[index].visible = show
        elif name in self.get_data_layers():
            index = self.find_layer_index(name)
            self.data[index].visible = show
        else:
            print(f"Layer {name} not found.")

    def set_layer_opacity(self, name: str, opacity: Optional[float] = 1) -> None:
        """Sets the visibility of a layer.

        Args:
            name (str): Name of the layer to set.
            opacity (float, optional): Opacity of the layer. Defaults to 1.
        """

        if name in self.get_tile_layers():
            index = self.find_layer_index(name)
            self.layout.mapbox.layers[index].opacity = opacity
        elif name in self.get_data_layers():
            index = self.find_layer_index(name)
            layer = self.data[index]
            if hasattr(layer, "opacity"):
                layer.opacity = opacity
            elif hasattr(layer, "marker"):
                layer.marker.opacity = opacity
        else:
            print(f"Layer {name} not found.")

    def add_tile_layer(
        self,
        url: str,
        name: Optional[str] = "TileLayer",
        attribution: Optional[str] = "",
        opacity: Optional[float] = 1.0,
        **kwargs,
    ) -> None:
        """Adds a TileLayer to the map.

        Args:
            url (str): The URL of the tile layer.
            name (str, optional): Name of the layer. Defaults to 'TileLayer'.
            attribution (str): The attribution to use. Defaults to "".
            opacity (float, optional): The opacity of the layer. Defaults to 1.
        """

        layer = {
            "below": "traces",
            "sourcetype": "raster",
            "sourceattribution": attribution,
            "source": [url],
            "opacity": opacity,
            "name": name,
        }
        layers = list(self.layout.mapbox.layers) + [layer]
        self.update_layout(mapbox_layers=layers)

    def add_cog_layer(
        self,
        url: str,
        name: Optional[str] = "Untitled",
        attribution: Optional[str] = "",
        opacity: Optional[float] = 1.0,
        bands: Optional[List] = None,
        titiler_endpoint: Optional[str] = None,
        **kwargs,
    ) -> None:
        """Adds a COG TileLayer to the map.

        Args:
            url (str): The URL of the COG tile layer, e.g., 'https://github.com/opengeos/data/releases/download/raster/Libya-2023-07-01.tif'
            name (str, optional): The layer name to use for the layer. Defaults to 'Untitled'.
            attribution (str, optional): The attribution to use. Defaults to ''.
            opacity (float, optional): The opacity of the layer. Defaults to 1.
            bands (list, optional): The bands to use. Defaults to None.
            titiler_endpoint (str, optional): Titiler endpoint. Defaults to "https://titiler.xyz".
            **kwargs: Arbitrary keyword arguments, including bidx, expression, nodata, unscale, resampling, rescale,
                color_formula, colormap, colormap_name, return_mask. See https://developmentseed.org/titiler/endpoints/cog/
                and https://cogeotiff.github.io/rio-tiler/colormap/. To select a certain bands, use bidx=[1, 2, 3].
                apply a rescaling to multiple bands, use something like `rescale=["164,223","130,211","99,212"]`.
        """
        tile_url = common.cog_tile(url, bands, titiler_endpoint, **kwargs)
        center = common.cog_center(url, titiler_endpoint)  # (lon, lat)
        self.add_tile_layer(tile_url, name, attribution, opacity)
        self.set_center(lon=center[0], lat=center[1], zoom=10)

    def add_stac_layer(
        self,
        url: str = None,
        collection: str = None,
        items: str = None,
        assets: str = None,
        bands: List = None,
        titiler_endpoint: Optional[str] = None,
        name: Optional[str] = "STAC Layer",
        attribution: Optional[str] = "",
        opacity: Optional[float] = 1.0,
        **kwargs,
    ) -> None:
        """Adds a STAC TileLayer to the map.

        Args:
            url (str): HTTP URL to a STAC item, e.g., https://canada-spot-ortho.s3.amazonaws.com/canada_spot_orthoimages/canada_spot5_orthoimages/S5_2007/S5_11055_6057_20070622/S5_11055_6057_20070622.json
            collection (str): The Microsoft Planetary Computer STAC collection ID, e.g., landsat-8-c2-l2.
            items (str): The Microsoft Planetary Computer STAC item ID, e.g., LC08_L2SP_047027_20201204_02_T1.
            assets (str | list): The Microsoft Planetary Computer STAC asset ID, e.g., ["SR_B7", "SR_B5", "SR_B4"].
            bands (list): A list of band names, e.g., ["SR_B7", "SR_B5", "SR_B4"]
            titiler_endpoint (str, optional): Titiler endpoint, e.g., "https://titiler.xyz", "planetary-computer", "pc". Defaults to None.
            name (str, optional): The layer name to use for the layer. Defaults to 'STAC Layer'.
            attribution (str, optional): The attribution to use. Defaults to ''.
            opacity (float, optional): The opacity of the layer. Defaults to 1.
        """
        tile_url = common.stac_tile(
            url, collection, items, assets, bands, titiler_endpoint, **kwargs
        )
        center = common.stac_center(url, collection, items, titiler_endpoint)
        self.add_tile_layer(tile_url, name, attribution, opacity)
        self.set_center(lon=center[0], lat=center[1], zoom=10)

    def add_mosaic_layer(
        self,
        url: str,
        titiler_endpoint: Optional[str] = None,
        name: Optional[str] = "Mosaic Layer",
        attribution: Optional[str] = "",
        opacity: Optional[float] = 1.0,
        **kwargs,
    ) -> None:
        """Adds a STAC TileLayer to the map.

        Args:
            url (str): HTTP URL to a MosaicJSON.
            titiler_endpoint (str, optional): Titiler endpoint, e.g., "https://titiler.xyz". Defaults to None.
            name (str, optional): The layer name to use for the layer. Defaults to 'Mosaic Layer'.
            attribution (str, optional): The attribution to use. Defaults to ''.
            opacity (float, optional): The opacity of the layer. Defaults to 1.
        """
        tile_url = common.mosaic_tile(url, titiler_endpoint, **kwargs)
        center = common.mosaic_info(url, titiler_endpoint)["center"]
        self.add_tile_layer(tile_url, name, attribution, opacity)
        self.set_center(lon=center[0], lat=center[1], zoom=10)

    def add_planet_by_month(
        self,
        year: Optional[int] = 2016,
        month: Optional[int] = 1,
        api_key: Optional[str] = None,
        token_name: Optional[str] = "PLANET_API_KEY",
        name: Optional[str] = None,
        attribution: str = "",
        opacity: Optional[float] = 1.0,
    ) -> None:
        """Adds Planet global mosaic by month to the map. To get a Planet API key, see https://developers.planet.com/quickstart/apis/

        Args:
            year (int, optional): The year of Planet global mosaic, must be >=2016. Defaults to 2016.
            month (int, optional): The month of Planet global mosaic, must be 1-12. Defaults to 1.
            api_key (str, optional): The Planet API key. Defaults to None.
            token_name (str, optional): The environment variable name of the API key. Defaults to "PLANET_API_KEY".
            name (str, optional): Name of the layer. Defaults to 'TileLayer'.
            attribution (str): The attribution to use. Defaults to "".
            opacity (float, optional): The opacity of the layer. Defaults to 1.
        """
        if name is None:
            name = str(year) + "-" + str(month).zfill(2)
        tile_url = common.planet_by_month(year, month, api_key, token_name)
        self.add_tile_layer(
            tile_url, name=name, attribution=attribution, opacity=opacity
        )

    def add_planet_by_quarter(
        self,
        year: Optional[int] = 2016,
        quarter: Optional[int] = 1,
        api_key: Optional[str] = None,
        token_name: Optional[str] = "PLANET_API_KEY",
        name: Optional[str] = None,
        attribution: str = "",
        opacity: Optional[float] = 1.0,
    ) -> None:
        """Adds Planet global mosaic by month to the map. To get a Planet API key, see https://developers.planet.com/quickstart/apis/

        Args:
            year (int, optional): The year of Planet global mosaic, must be >=2016. Defaults to 2016.
            quarter (int, optional): The quarter of Planet global mosaic, must be 1-4. Defaults to 1.
            api_key (str, optional): The Planet API key. Defaults to None.
            token_name (str, optional): The environment variable name of the API key. Defaults to "PLANET_API_KEY".
            name (str, optional): Name of the layer. Defaults to 'TileLayer'.
            attribution (str): The attribution to use. Defaults to "".
            opacity (float, optional): The opacity of the layer. Defaults to 1.
        """
        if name is None:
            name = str(year) + "-" + "q" + str(quarter)
        tile_url = common.planet_by_quarter(year, quarter, api_key, token_name)
        self.add_tile_layer(
            tile_url, name=name, attribution=attribution, opacity=opacity
        )

    def save(
        self,
        file: str,
        format: Optional[str] = None,
        width: Optional[int] = None,
        height: Optional[int] = None,
        scale: Optional[int] = None,
        **kwargs,
    ) -> None:
        """Convert a map to a static image and write it to a file or writeable object

        Args:
            file (str): A string representing a local file path or a writeable object (e.g. a pathlib.Path object or an open file descriptor)
            format (str, optional): The desired image format. One of png, jpg, jpeg, webp, svg, pdf, eps. Defaults to None.
            width (int, optional): The width of the exported image in layout pixels. If the `scale` property is 1.0, this will also be the width of the exported image in physical pixels.. Defaults to None.
            height (int, optional): The height of the exported image in layout pixels. If the `scale` property is 1.0, this will also be the height of the exported image in physical pixels.. Defaults to None.
            scale (int, optional): The scale factor to use when exporting the figure. A scale factor larger than 1.0 will increase the image resolution with respect to the figure's layout pixel dimensions. Whereas as scale factor of less than 1.0 will decrease the image resolution.. Defaults to None.
        """
        self.write_image(
            file, format=format, width=width, height=height, scale=scale, **kwargs
        )

    def add_choropleth_map(
        self,
        data: str,
        name: Optional[str] = None,
        z: Optional[str] = None,
        colorscale: Optional[str] = "Viridis",
        **kwargs,
    ) -> None:
        """Adds a choropleth map to the map.

        Args:
            data (str): File path to vector data, e.g., https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/countries.geojson
            name (str, optional): Name of the layer. Defaults to None.
            z (str, optional): Z value of the data. Defaults to None.
            colorscale (str, optional): Color scale of the data. Defaults to "Viridis".
        """
        common.check_package("geopandas")
        import json
        import geopandas as gpd

        gdf = gpd.read_file(data).to_crs(epsg=4326)
        geojson = json.loads(gdf.to_json())

        self.add_choroplethmapbox(
            geojson=geojson,
            locations=gdf.index,
            z=gdf[z],
            name=name,
            colorscale=colorscale,
            **kwargs,
        )

    def add_scatter_plot_demo(self, **kwargs) -> None:
        """Adds a scatter plot to the map."""
        lons = np.random.random(1000) * 360.0
        lats = np.random.random(1000) * 180.0 - 90.0
        z = np.random.random(1000) * 50.0
        self.add_scattermapbox(
            lon=lons, lat=lats, marker={"color": z}, name="Random points", **kwargs
        )

    def add_heatmap(
        self,
        data: Union[str, DataFrame],
        latitude: Optional[str] = "latitude",
        longitude: Optional[str] = "longitude",
        z: Optional[str] = "value",
        radius: Optional[int] = 10,
        colorscale: Optional[str] = None,
        name: Optional[str] = "Heat map",
        **kwargs,
    ) -> None:
        """Adds a heat map to the map. Reference: https://plotly.com/python/mapbox-density-heatmaps

        Args:
            data (str | pd.DataFrame): File path or HTTP URL to the input file or a . For example, https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv
            latitude (str, optional): The column name of latitude. Defaults to "latitude".
            longitude (str, optional): The column name of longitude. Defaults to "longitude".
            z (str, optional): The column name of z values. Defaults to "value".
            radius (int, optional): Radius of each “point” of the heatmap. Defaults to 25.
            colorscale (str, optional): Color scale of the data, e.g., Viridis. See https://plotly.com/python/builtin-colorscales. Defaults to None.
            name (str, optional): Layer name to use. Defaults to "Heat map".

        """

        if isinstance(data, str):
            try:
                df = pd.read_csv(data)
            except FileNotFoundError:
                raise FileNotFoundError(f"file path {data} not found")
            except Exception as other_error:
                raise ValueError(f"failed load data from {data}: {other_error}")
        elif isinstance(data, pd.DataFrame):
            df = data
        else:
            raise ValueError("data must be a DataFrame or a file path.")

        for column_data in [latitude, longitude, z]:
            if column_data not in df.columns:
                raise KeyError(
                    f"column {column_data} not found, available columns {', '.join(df.columns)}"
                )

        heatmap = go.Densitymapbox(
            lat=df[latitude],
            lon=df[longitude],
            z=df[z],
            radius=radius,
            colorscale=colorscale,
            name=name,
            **kwargs,
        )
        self.add_trace(heatmap)

    def add_heatmap_demo(self, **kwargs) -> None:
        """Adds a heatmap to the map."""
        quakes = pd.read_csv(
            "https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv"
        )
        heatmap = go.Densitymapbox(
            lat=quakes.Latitude,
            lon=quakes.Longitude,
            z=quakes.Magnitude,
            radius=10,
            name="Earthquake",
            **kwargs,
        )

        self.add_basemap("Esri.WorldTopoMap")
        self.add_trace(heatmap)

    def add_gdf_demo(
        self,
        gdf,
        label_col: Optional[str],
        color_col: Optional[str],
        color_continuous_scale: Optional[str] = "Viridis",
        **kwargs,
    ) -> None:
        common.check_package("geopandas", "https://geopandas.org")
        import geopandas as gpd

        geojson_url = str(gdf)

        if isinstance(gdf, str):
            gdf = gpd.read_file(gdf).to_crs(epsg=4326)

        fig = go.Choroplethmapbox(
            geojson=geojson_url,
            featureidkey="properties.{}".format(label_col),
            locations=gdf[label_col],
            z=gdf[color_col],
            autocolorscale=False,
            colorscale=color_continuous_scale,
            marker_line_color="peachpuff",
            colorbar=dict(
                title={"text": "Legend"},
                thickness=15,
                len=0.35,
                bgcolor="rgba(255,255,255,0.6)",
                xanchor="left",
                x=0.02,
                yanchor="bottom",
                y=0.05,
            ),
        )
        self.add_trace(fig)

    def add_gdf(
        self,
        gdf,
        label_col: Optional[str] = None,
        color_col: Optional[str] = None,
        labels=None,
        opacity: Optional[float] = 1.0,
        zoom: Optional[int] = None,
        color_continuous_scale: Optional[str] = "Viridis",
        **kwargs,
    ) -> None:
        """Adds a GeoDataFrame to the map.
        Args:
            gdf (GeoDataFrame): A GeoDataFrame.
            label_col (str, optional): The column name of locations. Defaults to None.
            color_col (str, optional): The column name of color. Defaults to None.
        """

        common.check_package("geopandas", "https://geopandas.org")
        import geopandas as gpd

        if isinstance(gdf, str):
            gdf = gpd.read_file(gdf)

        if not isinstance(gdf, gpd.GeoDataFrame):
            raise ValueError("gdf must be a GeoDataFrame.")

        gdf = gdf.to_crs(epsg=4326)
        # geom_type = gdf_geom_type(gdf)
        center_lon, center_lat = common.gdf_centroid(gdf)

        if isinstance(label_col, str):
            gdf = gdf.set_index(label_col)
            if label_col == color_col:
                gdf[label_col] = gdf.index
            label_col = gdf.index
        elif label_col is None:
            label_col = gdf.index

        if isinstance(color_col, str):
            if color_col not in gdf.columns:
                raise ValueError(
                    f"color must be a column name in the GeoDataFrame. Can be one of {','.join(gdf.columns)} "
                )
        fig = px.choropleth_mapbox(
            gdf,
            geojson=gdf.geometry,
            locations=label_col,
            color=color_col,
            color_continuous_scale=color_continuous_scale,
            opacity=opacity,
            labels=labels,
            # mapbox_style="carto-positron",
            **kwargs,
        )

        self.add_traces(fig.data)
        self.set_center(center_lat, center_lon, zoom)

    def add_geojson_layer(
        self,
        geojson_in: Union[str, Dict],
        name: str,
        color: Optional[str] = "blue",
        opacity: Optional[float] = 1,
    ) -> None:
        """Prepare proper and give style for different type of Geometry

        Args:
            in_geojson (str | dict): The file path or http URL to the input GeoJSON or a dictionary containing the geojson.
            name (str): Name for the Layer
            color (str, optional): Plain name for color (e.g: blue) or color code (e.g: #FF0000)
            opacity(float, optional): opacity of the layer in Map
        """

        import json
        import requests

        if isinstance(geojson_in, dict):
            data = geojson_in
        elif geojson_in.startswith("http"):
            data = requests.get(geojson_in).json()
        elif geojson_in.lower().endswith((".json", ".geojson")):
            with open(geojson_in) as fp:
                data = json.load(fp)
        else:
            data = geojson_in

        """ Only Checking Geometry of first feature( todo : handle multiple type of Geometry in same geojson ) """
        first_feature = data["features"][0]
        geometry_type = first_feature["geometry"]["type"]

        if geometry_type.lower() in ["polygon", "multipolygon"]:
            type = "fill"
        elif geometry_type.lower() in ["linstring", "multilinestring"]:
            type = "line"
        elif geometry_type.lower() in ["point", "multipoint"]:
            type = "circle"
        else:
            type = "fill"

        self.add_geojson(data, name, type, color, opacity)

    def add_geojson(
        self,
        data: Dict,
        name: str,
        type: Optional[str],
        color: Optional[str],
        opacity: Optional[float],
    ) -> None:
        """Add layers to the Map

        Args:
            data (dict): Geojson in Dict form
            name (str): Name for the Layer
            color (str, optional): Plain name for color (e.g: blue) or color code (e.g: #FF0000)
            opacity(float, optional): opacity of the layer in Map
        """

        new_layer = {
            "source": data,
            "name": name,
            "type": type,
            "opacity": opacity,
            "color": color,
        }
        if type == "circle":
            new_layer["circle"] = {"radius": 5}
        existing_layers = list(self.layout.mapbox.layers)

        existing_layers.append(new_layer)

        self.update_layout(mapbox={"layers": tuple(existing_layers)})

__init__(center=(20, 0), zoom=1, basemap='open-street-map', height=600, **kwargs)

Initializes a map. More info at https://plotly.com/python/mapbox-layers/

Parameters:

Name Type Description Default
center tuple

Center of the map. Defaults to (20, 0).

(20, 0)
zoom float

Zoom level of the map. Defaults to 1.

1
basemap str

Can be one of string from "open-street-map", "carto-positron", "carto-darkmatter", "stamen-terrain", "stamen-toner" or "stamen-watercolor" . Defaults to 'open-street-map'.

'open-street-map'
height int

Height of the map. Defaults to 600.

600
Source code in leafmap/plotlymap.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
def __init__(
    self,
    center: Optional[Tuple[float, float]] = (20, 0),
    zoom: Optional[float] = 1,
    basemap: Optional[str] = "open-street-map",
    height: Optional[int] = 600,
    **kwargs,
) -> None:
    """Initializes a map. More info at https://plotly.com/python/mapbox-layers/

    Args:
        center (tuple, optional): Center of the map. Defaults to (20, 0).
        zoom (float, optional): Zoom level of the map. Defaults to 1.
        basemap (str, optional): Can be one of string from "open-street-map", "carto-positron", "carto-darkmatter", "stamen-terrain", "stamen-toner" or "stamen-watercolor" . Defaults to 'open-street-map'.
        height (int, optional): Height of the map. Defaults to 600.
    """
    super().__init__(**kwargs)
    self.add_scattermapbox()
    self.update_layout(
        {
            "mapbox": {
                "style": basemap,
                "center": {"lat": center[0], "lon": center[1]},
                "zoom": zoom,
            },
            "margin": {"r": 0, "t": 0, "l": 0, "b": 0},
            "height": height,
        }
    )

add_basemap(basemap='ROADMAP')

Adds a basemap to the map.

Parameters:

Name Type Description Default
basemap str

Can be one of string from basemaps. Defaults to 'ROADMAP'.

'ROADMAP'
Source code in leafmap/plotlymap.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
def add_basemap(self, basemap: Optional[str] = "ROADMAP") -> None:
    """Adds a basemap to the map.

    Args:
        basemap (str, optional): Can be one of string from basemaps. Defaults to 'ROADMAP'.
    """
    if basemap not in basemaps:
        raise ValueError(
            f"Basemap {basemap} not found. Choose from {','.join(basemaps.keys())}"
        )

    if basemap in self.get_tile_layers():
        self.remove_basemap(basemap)
    layers = list(self.layout.mapbox.layers) + [basemaps[basemap]]
    self.update_layout(mapbox_layers=layers)

add_choropleth_map(data, name=None, z=None, colorscale='Viridis', **kwargs)

Adds a choropleth map to the map.

Parameters:

Name Type Description Default
data str

File path to vector data, e.g., https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/countries.geojson

required
name str

Name of the layer. Defaults to None.

None
z str

Z value of the data. Defaults to None.

None
colorscale str

Color scale of the data. Defaults to "Viridis".

'Viridis'
Source code in leafmap/plotlymap.py
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
def add_choropleth_map(
    self,
    data: str,
    name: Optional[str] = None,
    z: Optional[str] = None,
    colorscale: Optional[str] = "Viridis",
    **kwargs,
) -> None:
    """Adds a choropleth map to the map.

    Args:
        data (str): File path to vector data, e.g., https://raw.githubusercontent.com/opengeos/leafmap/master/examples/data/countries.geojson
        name (str, optional): Name of the layer. Defaults to None.
        z (str, optional): Z value of the data. Defaults to None.
        colorscale (str, optional): Color scale of the data. Defaults to "Viridis".
    """
    common.check_package("geopandas")
    import json
    import geopandas as gpd

    gdf = gpd.read_file(data).to_crs(epsg=4326)
    geojson = json.loads(gdf.to_json())

    self.add_choroplethmapbox(
        geojson=geojson,
        locations=gdf.index,
        z=gdf[z],
        name=name,
        colorscale=colorscale,
        **kwargs,
    )

add_cog_layer(url, name='Untitled', attribution='', opacity=1.0, bands=None, titiler_endpoint=None, **kwargs)

Adds a COG TileLayer to the map.

Parameters:

Name Type Description Default
url str

The URL of the COG tile layer, e.g., 'https://github.com/opengeos/data/releases/download/raster/Libya-2023-07-01.tif'

required
name str

The layer name to use for the layer. Defaults to 'Untitled'.

'Untitled'
attribution str

The attribution to use. Defaults to ''.

''
opacity float

The opacity of the layer. Defaults to 1.

1.0
bands list

The bands to use. Defaults to None.

None
titiler_endpoint str

Titiler endpoint. Defaults to "https://titiler.xyz".

None
**kwargs

Arbitrary keyword arguments, including bidx, expression, nodata, unscale, resampling, rescale, color_formula, colormap, colormap_name, return_mask. See https://developmentseed.org/titiler/endpoints/cog/ and https://cogeotiff.github.io/rio-tiler/colormap/. To select a certain bands, use bidx=[1, 2, 3]. apply a rescaling to multiple bands, use something like rescale=["164,223","130,211","99,212"].

{}
Source code in leafmap/plotlymap.py
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
def add_cog_layer(
    self,
    url: str,
    name: Optional[str] = "Untitled",
    attribution: Optional[str] = "",
    opacity: Optional[float] = 1.0,
    bands: Optional[List] = None,
    titiler_endpoint: Optional[str] = None,
    **kwargs,
) -> None:
    """Adds a COG TileLayer to the map.

    Args:
        url (str): The URL of the COG tile layer, e.g., 'https://github.com/opengeos/data/releases/download/raster/Libya-2023-07-01.tif'
        name (str, optional): The layer name to use for the layer. Defaults to 'Untitled'.
        attribution (str, optional): The attribution to use. Defaults to ''.
        opacity (float, optional): The opacity of the layer. Defaults to 1.
        bands (list, optional): The bands to use. Defaults to None.
        titiler_endpoint (str, optional): Titiler endpoint. Defaults to "https://titiler.xyz".
        **kwargs: Arbitrary keyword arguments, including bidx, expression, nodata, unscale, resampling, rescale,
            color_formula, colormap, colormap_name, return_mask. See https://developmentseed.org/titiler/endpoints/cog/
            and https://cogeotiff.github.io/rio-tiler/colormap/. To select a certain bands, use bidx=[1, 2, 3].
            apply a rescaling to multiple bands, use something like `rescale=["164,223","130,211","99,212"]`.
    """
    tile_url = common.cog_tile(url, bands, titiler_endpoint, **kwargs)
    center = common.cog_center(url, titiler_endpoint)  # (lon, lat)
    self.add_tile_layer(tile_url, name, attribution, opacity)
    self.set_center(lon=center[0], lat=center[1], zoom=10)

add_controls(controls)

Adds controls to the map.

Parameters:

Name Type Description Default
controls list

List of controls to add, e.g., ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape'] See https://bit.ly/33Tmqxr

required
Source code in leafmap/plotlymap.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
def add_controls(self, controls: List) -> None:
    """Adds controls to the map.

    Args:
        controls (list): List of controls to add, e.g., ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape'] See https://bit.ly/33Tmqxr
    """
    if isinstance(controls, str):
        controls = [controls]
    elif not isinstance(controls, list):
        raise ValueError(
            "Controls must be a string or a list of strings. See https://bit.ly/33Tmqxr"
        )

    self.update_layout(modebar_add=controls)

add_gdf(gdf, label_col=None, color_col=None, labels=None, opacity=1.0, zoom=None, color_continuous_scale='Viridis', **kwargs)

Adds a GeoDataFrame to the map. Args: gdf (GeoDataFrame): A GeoDataFrame. label_col (str, optional): The column name of locations. Defaults to None. color_col (str, optional): The column name of color. Defaults to None.

Source code in leafmap/plotlymap.py
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
def add_gdf(
    self,
    gdf,
    label_col: Optional[str] = None,
    color_col: Optional[str] = None,
    labels=None,
    opacity: Optional[float] = 1.0,
    zoom: Optional[int] = None,
    color_continuous_scale: Optional[str] = "Viridis",
    **kwargs,
) -> None:
    """Adds a GeoDataFrame to the map.
    Args:
        gdf (GeoDataFrame): A GeoDataFrame.
        label_col (str, optional): The column name of locations. Defaults to None.
        color_col (str, optional): The column name of color. Defaults to None.
    """

    common.check_package("geopandas", "https://geopandas.org")
    import geopandas as gpd

    if isinstance(gdf, str):
        gdf = gpd.read_file(gdf)

    if not isinstance(gdf, gpd.GeoDataFrame):
        raise ValueError("gdf must be a GeoDataFrame.")

    gdf = gdf.to_crs(epsg=4326)
    # geom_type = gdf_geom_type(gdf)
    center_lon, center_lat = common.gdf_centroid(gdf)

    if isinstance(label_col, str):
        gdf = gdf.set_index(label_col)
        if label_col == color_col:
            gdf[label_col] = gdf.index
        label_col = gdf.index
    elif label_col is None:
        label_col = gdf.index

    if isinstance(color_col, str):
        if color_col not in gdf.columns:
            raise ValueError(
                f"color must be a column name in the GeoDataFrame. Can be one of {','.join(gdf.columns)} "
            )
    fig = px.choropleth_mapbox(
        gdf,
        geojson=gdf.geometry,
        locations=label_col,
        color=color_col,
        color_continuous_scale=color_continuous_scale,
        opacity=opacity,
        labels=labels,
        # mapbox_style="carto-positron",
        **kwargs,
    )

    self.add_traces(fig.data)
    self.set_center(center_lat, center_lon, zoom)

add_geojson(data, name, type, color, opacity)

Add layers to the Map

Parameters:

Name Type Description Default
data dict

Geojson in Dict form

required
name str

Name for the Layer

required
color str

Plain name for color (e.g: blue) or color code (e.g: #FF0000)

required
opacity(float, optional

opacity of the layer in Map

required
Source code in leafmap/plotlymap.py
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
def add_geojson(
    self,
    data: Dict,
    name: str,
    type: Optional[str],
    color: Optional[str],
    opacity: Optional[float],
) -> None:
    """Add layers to the Map

    Args:
        data (dict): Geojson in Dict form
        name (str): Name for the Layer
        color (str, optional): Plain name for color (e.g: blue) or color code (e.g: #FF0000)
        opacity(float, optional): opacity of the layer in Map
    """

    new_layer = {
        "source": data,
        "name": name,
        "type": type,
        "opacity": opacity,
        "color": color,
    }
    if type == "circle":
        new_layer["circle"] = {"radius": 5}
    existing_layers = list(self.layout.mapbox.layers)

    existing_layers.append(new_layer)

    self.update_layout(mapbox={"layers": tuple(existing_layers)})

add_geojson_layer(geojson_in, name, color='blue', opacity=1)

Prepare proper and give style for different type of Geometry

Parameters:

Name Type Description Default
in_geojson str | dict

The file path or http URL to the input GeoJSON or a dictionary containing the geojson.

required
name str

Name for the Layer

required
color str

Plain name for color (e.g: blue) or color code (e.g: #FF0000)

'blue'
opacity(float, optional

opacity of the layer in Map

required
Source code in leafmap/plotlymap.py
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
def add_geojson_layer(
    self,
    geojson_in: Union[str, Dict],
    name: str,
    color: Optional[str] = "blue",
    opacity: Optional[float] = 1,
) -> None:
    """Prepare proper and give style for different type of Geometry

    Args:
        in_geojson (str | dict): The file path or http URL to the input GeoJSON or a dictionary containing the geojson.
        name (str): Name for the Layer
        color (str, optional): Plain name for color (e.g: blue) or color code (e.g: #FF0000)
        opacity(float, optional): opacity of the layer in Map
    """

    import json
    import requests

    if isinstance(geojson_in, dict):
        data = geojson_in
    elif geojson_in.startswith("http"):
        data = requests.get(geojson_in).json()
    elif geojson_in.lower().endswith((".json", ".geojson")):
        with open(geojson_in) as fp:
            data = json.load(fp)
    else:
        data = geojson_in

    """ Only Checking Geometry of first feature( todo : handle multiple type of Geometry in same geojson ) """
    first_feature = data["features"][0]
    geometry_type = first_feature["geometry"]["type"]

    if geometry_type.lower() in ["polygon", "multipolygon"]:
        type = "fill"
    elif geometry_type.lower() in ["linstring", "multilinestring"]:
        type = "line"
    elif geometry_type.lower() in ["point", "multipoint"]:
        type = "circle"
    else:
        type = "fill"

    self.add_geojson(data, name, type, color, opacity)

add_heatmap(data, latitude='latitude', longitude='longitude', z='value', radius=10, colorscale=None, name='Heat map', **kwargs)

Adds a heat map to the map. Reference: https://plotly.com/python/mapbox-density-heatmaps

Parameters:

Name Type Description Default
data str | DataFrame

File path or HTTP URL to the input file or a . For example, https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv

required
latitude str

The column name of latitude. Defaults to "latitude".

'latitude'
longitude str

The column name of longitude. Defaults to "longitude".

'longitude'
z str

The column name of z values. Defaults to "value".

'value'
radius int

Radius of each “point” of the heatmap. Defaults to 25.

10
colorscale str

Color scale of the data, e.g., Viridis. See https://plotly.com/python/builtin-colorscales. Defaults to None.

None
name str

Layer name to use. Defaults to "Heat map".

'Heat map'
Source code in leafmap/plotlymap.py
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
def add_heatmap(
    self,
    data: Union[str, DataFrame],
    latitude: Optional[str] = "latitude",
    longitude: Optional[str] = "longitude",
    z: Optional[str] = "value",
    radius: Optional[int] = 10,
    colorscale: Optional[str] = None,
    name: Optional[str] = "Heat map",
    **kwargs,
) -> None:
    """Adds a heat map to the map. Reference: https://plotly.com/python/mapbox-density-heatmaps

    Args:
        data (str | pd.DataFrame): File path or HTTP URL to the input file or a . For example, https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv
        latitude (str, optional): The column name of latitude. Defaults to "latitude".
        longitude (str, optional): The column name of longitude. Defaults to "longitude".
        z (str, optional): The column name of z values. Defaults to "value".
        radius (int, optional): Radius of each “point” of the heatmap. Defaults to 25.
        colorscale (str, optional): Color scale of the data, e.g., Viridis. See https://plotly.com/python/builtin-colorscales. Defaults to None.
        name (str, optional): Layer name to use. Defaults to "Heat map".

    """

    if isinstance(data, str):
        try:
            df = pd.read_csv(data)
        except FileNotFoundError:
            raise FileNotFoundError(f"file path {data} not found")
        except Exception as other_error:
            raise ValueError(f"failed load data from {data}: {other_error}")
    elif isinstance(data, pd.DataFrame):
        df = data
    else:
        raise ValueError("data must be a DataFrame or a file path.")

    for column_data in [latitude, longitude, z]:
        if column_data not in df.columns:
            raise KeyError(
                f"column {column_data} not found, available columns {', '.join(df.columns)}"
            )

    heatmap = go.Densitymapbox(
        lat=df[latitude],
        lon=df[longitude],
        z=df[z],
        radius=radius,
        colorscale=colorscale,
        name=name,
        **kwargs,
    )
    self.add_trace(heatmap)

add_heatmap_demo(**kwargs)

Adds a heatmap to the map.

Source code in leafmap/plotlymap.py
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
def add_heatmap_demo(self, **kwargs) -> None:
    """Adds a heatmap to the map."""
    quakes = pd.read_csv(
        "https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv"
    )
    heatmap = go.Densitymapbox(
        lat=quakes.Latitude,
        lon=quakes.Longitude,
        z=quakes.Magnitude,
        radius=10,
        name="Earthquake",
        **kwargs,
    )

    self.add_basemap("Esri.WorldTopoMap")
    self.add_trace(heatmap)

add_layer(layer, name=None, **kwargs)

Adds a layer to the map.

Parameters:

Name Type Description Default
layer graph_objects

Layer to add.

required
name str

Name of the layer. Defaults to None.

None
Source code in leafmap/plotlymap.py
235
236
237
238
239
240
241
242
243
244
def add_layer(self, layer, name: Optional[str] = None, **kwargs):
    """Adds a layer to the map.

    Args:
        layer (plotly.graph_objects): Layer to add.
        name (str, optional): Name of the layer. Defaults to None.
    """
    if isinstance(name, str):
        layer.name = name
    self.add_trace(layer, **kwargs)

add_mapbox_layer(style, access_token=None)

Adds a mapbox layer to the map.

Parameters:

Name Type Description Default
layer str | dict

Layer to add. Can be "basic", "streets", "outdoors", "light", "dark", "satellite", or "satellite-streets". See https://plotly.com/python/mapbox-layers/ and https://docs.mapbox.com/mapbox-gl-js/style-spec/

required
access_token str

The Mapbox Access token. It can be set as an environment variable "MAPBOX_TOKEN". Defaults to None.

None
Source code in leafmap/plotlymap.py
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def add_mapbox_layer(self, style: Union[str, Dict], access_token=None) -> None:
    """Adds a mapbox layer to the map.

    Args:
        layer (str | dict): Layer to add. Can be "basic", "streets", "outdoors", "light", "dark", "satellite", or "satellite-streets". See https://plotly.com/python/mapbox-layers/ and https://docs.mapbox.com/mapbox-gl-js/style-spec/
        access_token (str, optional): The Mapbox Access token. It can be set as an environment variable "MAPBOX_TOKEN". Defaults to None.
    """

    if access_token is None:
        access_token = os.environ.get("MAPBOX_TOKEN")

    self.update_layout(
        mapbox_style=style, mapbox_layers=[], mapbox_accesstoken=access_token
    )

add_mosaic_layer(url, titiler_endpoint=None, name='Mosaic Layer', attribution='', opacity=1.0, **kwargs)

Adds a STAC TileLayer to the map.

Parameters:

Name Type Description Default
url str

HTTP URL to a MosaicJSON.

required
titiler_endpoint str

Titiler endpoint, e.g., "https://titiler.xyz". Defaults to None.

None
name str

The layer name to use for the layer. Defaults to 'Mosaic Layer'.

'Mosaic Layer'
attribution str

The attribution to use. Defaults to ''.

''
opacity float

The opacity of the layer. Defaults to 1.

1.0
Source code in leafmap/plotlymap.py
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
def add_mosaic_layer(
    self,
    url: str,
    titiler_endpoint: Optional[str] = None,
    name: Optional[str] = "Mosaic Layer",
    attribution: Optional[str] = "",
    opacity: Optional[float] = 1.0,
    **kwargs,
) -> None:
    """Adds a STAC TileLayer to the map.

    Args:
        url (str): HTTP URL to a MosaicJSON.
        titiler_endpoint (str, optional): Titiler endpoint, e.g., "https://titiler.xyz". Defaults to None.
        name (str, optional): The layer name to use for the layer. Defaults to 'Mosaic Layer'.
        attribution (str, optional): The attribution to use. Defaults to ''.
        opacity (float, optional): The opacity of the layer. Defaults to 1.
    """
    tile_url = common.mosaic_tile(url, titiler_endpoint, **kwargs)
    center = common.mosaic_info(url, titiler_endpoint)["center"]
    self.add_tile_layer(tile_url, name, attribution, opacity)
    self.set_center(lon=center[0], lat=center[1], zoom=10)

add_planet_by_month(year=2016, month=1, api_key=None, token_name='PLANET_API_KEY', name=None, attribution='', opacity=1.0)

Adds Planet global mosaic by month to the map. To get a Planet API key, see https://developers.planet.com/quickstart/apis/

Parameters:

Name Type Description Default
year int

The year of Planet global mosaic, must be >=2016. Defaults to 2016.

2016
month int

The month of Planet global mosaic, must be 1-12. Defaults to 1.

1
api_key str

The Planet API key. Defaults to None.

None
token_name str

The environment variable name of the API key. Defaults to "PLANET_API_KEY".

'PLANET_API_KEY'
name str

Name of the layer. Defaults to 'TileLayer'.

None
attribution str

The attribution to use. Defaults to "".

''
opacity float

The opacity of the layer. Defaults to 1.

1.0
Source code in leafmap/plotlymap.py
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
def add_planet_by_month(
    self,
    year: Optional[int] = 2016,
    month: Optional[int] = 1,
    api_key: Optional[str] = None,
    token_name: Optional[str] = "PLANET_API_KEY",
    name: Optional[str] = None,
    attribution: str = "",
    opacity: Optional[float] = 1.0,
) -> None:
    """Adds Planet global mosaic by month to the map. To get a Planet API key, see https://developers.planet.com/quickstart/apis/

    Args:
        year (int, optional): The year of Planet global mosaic, must be >=2016. Defaults to 2016.
        month (int, optional): The month of Planet global mosaic, must be 1-12. Defaults to 1.
        api_key (str, optional): The Planet API key. Defaults to None.
        token_name (str, optional): The environment variable name of the API key. Defaults to "PLANET_API_KEY".
        name (str, optional): Name of the layer. Defaults to 'TileLayer'.
        attribution (str): The attribution to use. Defaults to "".
        opacity (float, optional): The opacity of the layer. Defaults to 1.
    """
    if name is None:
        name = str(year) + "-" + str(month).zfill(2)
    tile_url = common.planet_by_month(year, month, api_key, token_name)
    self.add_tile_layer(
        tile_url, name=name, attribution=attribution, opacity=opacity
    )

add_planet_by_quarter(year=2016, quarter=1, api_key=None, token_name='PLANET_API_KEY', name=None, attribution='', opacity=1.0)

Adds Planet global mosaic by month to the map. To get a Planet API key, see https://developers.planet.com/quickstart/apis/

Parameters:

Name Type Description Default
year int

The year of Planet global mosaic, must be >=2016. Defaults to 2016.

2016
quarter int

The quarter of Planet global mosaic, must be 1-4. Defaults to 1.

1
api_key str

The Planet API key. Defaults to None.

None
token_name str

The environment variable name of the API key. Defaults to "PLANET_API_KEY".

'PLANET_API_KEY'
name str

Name of the layer. Defaults to 'TileLayer'.

None
attribution str

The attribution to use. Defaults to "".

''
opacity float

The opacity of the layer. Defaults to 1.

1.0
Source code in leafmap/plotlymap.py
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
def add_planet_by_quarter(
    self,
    year: Optional[int] = 2016,
    quarter: Optional[int] = 1,
    api_key: Optional[str] = None,
    token_name: Optional[str] = "PLANET_API_KEY",
    name: Optional[str] = None,
    attribution: str = "",
    opacity: Optional[float] = 1.0,
) -> None:
    """Adds Planet global mosaic by month to the map. To get a Planet API key, see https://developers.planet.com/quickstart/apis/

    Args:
        year (int, optional): The year of Planet global mosaic, must be >=2016. Defaults to 2016.
        quarter (int, optional): The quarter of Planet global mosaic, must be 1-4. Defaults to 1.
        api_key (str, optional): The Planet API key. Defaults to None.
        token_name (str, optional): The environment variable name of the API key. Defaults to "PLANET_API_KEY".
        name (str, optional): Name of the layer. Defaults to 'TileLayer'.
        attribution (str): The attribution to use. Defaults to "".
        opacity (float, optional): The opacity of the layer. Defaults to 1.
    """
    if name is None:
        name = str(year) + "-" + "q" + str(quarter)
    tile_url = common.planet_by_quarter(year, quarter, api_key, token_name)
    self.add_tile_layer(
        tile_url, name=name, attribution=attribution, opacity=opacity
    )

add_scatter_plot_demo(**kwargs)

Adds a scatter plot to the map.

Source code in leafmap/plotlymap.py
598
599
600
601
602
603
604
605
def add_scatter_plot_demo(self, **kwargs) -> None:
    """Adds a scatter plot to the map."""
    lons = np.random.random(1000) * 360.0
    lats = np.random.random(1000) * 180.0 - 90.0
    z = np.random.random(1000) * 50.0
    self.add_scattermapbox(
        lon=lons, lat=lats, marker={"color": z}, name="Random points", **kwargs
    )

add_stac_layer(url=None, collection=None, items=None, assets=None, bands=None, titiler_endpoint=None, name='STAC Layer', attribution='', opacity=1.0, **kwargs)

Adds a STAC TileLayer to the map.

Parameters:

Name Type Description Default
url str

HTTP URL to a STAC item, e.g., https://canada-spot-ortho.s3.amazonaws.com/canada_spot_orthoimages/canada_spot5_orthoimages/S5_2007/S5_11055_6057_20070622/S5_11055_6057_20070622.json

None
collection str

The Microsoft Planetary Computer STAC collection ID, e.g., landsat-8-c2-l2.

None
items str

The Microsoft Planetary Computer STAC item ID, e.g., LC08_L2SP_047027_20201204_02_T1.

None
assets str | list

The Microsoft Planetary Computer STAC asset ID, e.g., ["SR_B7", "SR_B5", "SR_B4"].

None
bands list

A list of band names, e.g., ["SR_B7", "SR_B5", "SR_B4"]

None
titiler_endpoint str

Titiler endpoint, e.g., "https://titiler.xyz", "planetary-computer", "pc". Defaults to None.

None
name str

The layer name to use for the layer. Defaults to 'STAC Layer'.

'STAC Layer'
attribution str

The attribution to use. Defaults to ''.

''
opacity float

The opacity of the layer. Defaults to 1.

1.0
Source code in leafmap/plotlymap.py
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
def add_stac_layer(
    self,
    url: str = None,
    collection: str = None,
    items: str = None,
    assets: str = None,
    bands: List = None,
    titiler_endpoint: Optional[str] = None,
    name: Optional[str] = "STAC Layer",
    attribution: Optional[str] = "",
    opacity: Optional[float] = 1.0,
    **kwargs,
) -> None:
    """Adds a STAC TileLayer to the map.

    Args:
        url (str): HTTP URL to a STAC item, e.g., https://canada-spot-ortho.s3.amazonaws.com/canada_spot_orthoimages/canada_spot5_orthoimages/S5_2007/S5_11055_6057_20070622/S5_11055_6057_20070622.json
        collection (str): The Microsoft Planetary Computer STAC collection ID, e.g., landsat-8-c2-l2.
        items (str): The Microsoft Planetary Computer STAC item ID, e.g., LC08_L2SP_047027_20201204_02_T1.
        assets (str | list): The Microsoft Planetary Computer STAC asset ID, e.g., ["SR_B7", "SR_B5", "SR_B4"].
        bands (list): A list of band names, e.g., ["SR_B7", "SR_B5", "SR_B4"]
        titiler_endpoint (str, optional): Titiler endpoint, e.g., "https://titiler.xyz", "planetary-computer", "pc". Defaults to None.
        name (str, optional): The layer name to use for the layer. Defaults to 'STAC Layer'.
        attribution (str, optional): The attribution to use. Defaults to ''.
        opacity (float, optional): The opacity of the layer. Defaults to 1.
    """
    tile_url = common.stac_tile(
        url, collection, items, assets, bands, titiler_endpoint, **kwargs
    )
    center = common.stac_center(url, collection, items, titiler_endpoint)
    self.add_tile_layer(tile_url, name, attribution, opacity)
    self.set_center(lon=center[0], lat=center[1], zoom=10)

add_tile_layer(url, name='TileLayer', attribution='', opacity=1.0, **kwargs)

Adds a TileLayer to the map.

Parameters:

Name Type Description Default
url str

The URL of the tile layer.

required
name str

Name of the layer. Defaults to 'TileLayer'.

'TileLayer'
attribution str

The attribution to use. Defaults to "".

''
opacity float

The opacity of the layer. Defaults to 1.

1.0
Source code in leafmap/plotlymap.py
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
def add_tile_layer(
    self,
    url: str,
    name: Optional[str] = "TileLayer",
    attribution: Optional[str] = "",
    opacity: Optional[float] = 1.0,
    **kwargs,
) -> None:
    """Adds a TileLayer to the map.

    Args:
        url (str): The URL of the tile layer.
        name (str, optional): Name of the layer. Defaults to 'TileLayer'.
        attribution (str): The attribution to use. Defaults to "".
        opacity (float, optional): The opacity of the layer. Defaults to 1.
    """

    layer = {
        "below": "traces",
        "sourcetype": "raster",
        "sourceattribution": attribution,
        "source": [url],
        "opacity": opacity,
        "name": name,
    }
    layers = list(self.layout.mapbox.layers) + [layer]
    self.update_layout(mapbox_layers=layers)

clear_controls()

Removes all controls from the map.

Source code in leafmap/plotlymap.py
138
139
140
141
142
143
144
145
146
147
def clear_controls(self):
    """Removes all controls from the map."""
    config = {
        "scrollZoom": True,
        "displayModeBar": False,
        "editable": True,
        "showLink": False,
        "displaylogo": False,
    }
    self.show(toolbar=False, config=config)

clear_layers(clear_basemap=False)

Clears all layers from the map.

Parameters:

Name Type Description Default
clear_basemap bool

If True, clears the basemap. Defaults to False.

False
Source code in leafmap/plotlymap.py
259
260
261
262
263
264
265
266
267
268
269
def clear_layers(self, clear_basemap: Optional[bool] = False):
    """Clears all layers from the map.

    Args:
        clear_basemap (bool, optional): If True, clears the basemap. Defaults to False.
    """
    if clear_basemap:
        self.data = []
    else:
        if len(self.data) > 1:
            self.data = self.data[:1]

find_layer_index(name)

Finds the index of a layer.

Parameters:

Name Type Description Default
name str

Name of the layer to find.

required

Returns:

Name Type Description
int int

Index of the layer.

Source code in leafmap/plotlymap.py
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
def find_layer_index(self, name: str) -> int:
    """Finds the index of a layer.

    Args:
        name (str): Name of the layer to find.

    Returns:
        int: Index of the layer.
    """
    for i, layer in enumerate(self.data):
        if layer.name == name:
            return i

    for i, layer in enumerate(self.layout.mapbox.layers):
        if layer["name"] == name:
            return i

    return None

get_data_layers()

Returns a dictionary of data layers in the map.

Returns:

Name Type Description
dict Dict

A dictionary of data layers in the map.

Source code in leafmap/plotlymap.py
303
304
305
306
307
308
309
310
311
312
313
314
315
316
def get_data_layers(self) -> Dict:
    """Returns a dictionary of data layers in the map.

    Returns:
        dict: A dictionary of data layers in the map.
    """

    layers = {}

    for layer in self.data:
        if layer.name is not None and layer.name != "trace 0":
            layers[layer.name] = layer

    return layers

get_layers()

Returns a dictionary of all layers in the map. Returns: dict: A dictionary of all layers in the map.

Source code in leafmap/plotlymap.py
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def get_layers(self) -> Dict:
    """Returns a dictionary of all layers in the map.
    Returns:
        dict: A dictionary of all layers in the map.
    """
    layers = {}

    for layer in self.layout.mapbox.layers:
        if layer["name"] is not None:
            layers[layer["name"]] = layer

    for layer in self.data:
        if layer.name is not None and layer.name != "trace 0":
            layers[layer.name] = layer

    return layers

get_tile_layers()

Returns a dictionary of tile layers in the map.

Returns:

Name Type Description
dict Dict

A dictionary of tile layers in the map.

Source code in leafmap/plotlymap.py
288
289
290
291
292
293
294
295
296
297
298
299
300
301
def get_tile_layers(self) -> Dict:
    """Returns a dictionary of tile layers in the map.

    Returns:
        dict: A dictionary of tile layers in the map.
    """

    layers = {}

    for layer in self.layout.mapbox.layers:
        if layer["name"] is not None:
            layers[layer["name"]] = layer

    return layers

remove_basemap(name)

Removes a basemap from the map.

Parameters:

Name Type Description Default
name str

Name of the basemap to remove.

required
Source code in leafmap/plotlymap.py
210
211
212
213
214
215
216
217
218
def remove_basemap(self, name: str) -> None:
    """Removes a basemap from the map.

    Args:
        name (str): Name of the basemap to remove.
    """
    layers = list(self.layout.mapbox.layers)
    layers = [layer for layer in layers if layer["name"] != name]
    self.layout.mapbox.layers = layers

remove_controls(controls)

Removes controls to the map.

Parameters:

Name Type Description Default
controls list

List of controls to remove, e.g., ["zoomin", "zoomout", "toimage", "pan", "resetview"]. See https://bit.ly/3Jk7wkb

required
Source code in leafmap/plotlymap.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
def remove_controls(self, controls: List):
    """Removes controls to the map.

    Args:
        controls (list): List of controls to remove, e.g., ["zoomin", "zoomout", "toimage", "pan", "resetview"]. See https://bit.ly/3Jk7wkb
    """
    if isinstance(controls, str):
        controls = [controls]
    elif not isinstance(controls, list):
        raise ValueError(
            "Controls must be a string or a list of strings. See https://bit.ly/3Jk7wkb"
        )

    self.update_layout(modebar_remove=controls)

remove_layer(name)

Removes a layer from the map.

Parameters:

Name Type Description Default
name str

Name of the layer to remove.

required
Source code in leafmap/plotlymap.py
246
247
248
249
250
251
252
253
254
255
256
257
def remove_layer(self, name: str) -> None:
    """Removes a layer from the map.

    Args:
        name (str): Name of the layer to remove.
    """
    if name in self.get_data_layers():
        self.data = [layer for layer in self.data if layer.name != name]
    elif name in self.get_tile_layers():
        self.layout.mapbox.layers = [
            layer for layer in self.layout.mapbox.layers if layer["name"] != name
        ]

save(file, format=None, width=None, height=None, scale=None, **kwargs)

Convert a map to a static image and write it to a file or writeable object

Parameters:

Name Type Description Default
file str

A string representing a local file path or a writeable object (e.g. a pathlib.Path object or an open file descriptor)

required
format str

The desired image format. One of png, jpg, jpeg, webp, svg, pdf, eps. Defaults to None.

None
width int

The width of the exported image in layout pixels. If the scale property is 1.0, this will also be the width of the exported image in physical pixels.. Defaults to None.

None
height int

The height of the exported image in layout pixels. If the scale property is 1.0, this will also be the height of the exported image in physical pixels.. Defaults to None.

None
scale int

The scale factor to use when exporting the figure. A scale factor larger than 1.0 will increase the image resolution with respect to the figure's layout pixel dimensions. Whereas as scale factor of less than 1.0 will decrease the image resolution.. Defaults to None.

None
Source code in leafmap/plotlymap.py
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
def save(
    self,
    file: str,
    format: Optional[str] = None,
    width: Optional[int] = None,
    height: Optional[int] = None,
    scale: Optional[int] = None,
    **kwargs,
) -> None:
    """Convert a map to a static image and write it to a file or writeable object

    Args:
        file (str): A string representing a local file path or a writeable object (e.g. a pathlib.Path object or an open file descriptor)
        format (str, optional): The desired image format. One of png, jpg, jpeg, webp, svg, pdf, eps. Defaults to None.
        width (int, optional): The width of the exported image in layout pixels. If the `scale` property is 1.0, this will also be the width of the exported image in physical pixels.. Defaults to None.
        height (int, optional): The height of the exported image in layout pixels. If the `scale` property is 1.0, this will also be the height of the exported image in physical pixels.. Defaults to None.
        scale (int, optional): The scale factor to use when exporting the figure. A scale factor larger than 1.0 will increase the image resolution with respect to the figure's layout pixel dimensions. Whereas as scale factor of less than 1.0 will decrease the image resolution.. Defaults to None.
    """
    self.write_image(
        file, format=format, width=width, height=height, scale=scale, **kwargs
    )

set_center(lat, lon, zoom=None)

Sets the center of the map.

Parameters:

Name Type Description Default
lat float

Latitude.

required
lon float

Longitude.

required
zoom int

Zoom level of the map. Defaults to None.

None
Source code in leafmap/plotlymap.py
179
180
181
182
183
184
185
186
187
188
189
190
191
192
def set_center(self, lat: float, lon: float, zoom: Optional[float] = None) -> None:
    """Sets the center of the map.

    Args:
        lat (float): Latitude.
        lon (float): Longitude.
        zoom (int, optional): Zoom level of the map. Defaults to None.
    """
    self.update_layout(
        mapbox=dict(
            center=dict(lat=lat, lon=lon),
            zoom=zoom if zoom is not None else self.layout.mapbox.zoom,
        )
    )

set_layer_opacity(name, opacity=1)

Sets the visibility of a layer.

Parameters:

Name Type Description Default
name str

Name of the layer to set.

required
opacity float

Opacity of the layer. Defaults to 1.

1
Source code in leafmap/plotlymap.py
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
def set_layer_opacity(self, name: str, opacity: Optional[float] = 1) -> None:
    """Sets the visibility of a layer.

    Args:
        name (str): Name of the layer to set.
        opacity (float, optional): Opacity of the layer. Defaults to 1.
    """

    if name in self.get_tile_layers():
        index = self.find_layer_index(name)
        self.layout.mapbox.layers[index].opacity = opacity
    elif name in self.get_data_layers():
        index = self.find_layer_index(name)
        layer = self.data[index]
        if hasattr(layer, "opacity"):
            layer.opacity = opacity
        elif hasattr(layer, "marker"):
            layer.marker.opacity = opacity
    else:
        print(f"Layer {name} not found.")

set_layer_visibility(name, show=True)

Sets the visibility of a layer.

Parameters:

Name Type Description Default
name str

Name of the layer to set.

required
show bool

If True, shows the layer. Defaults to True.

True
Source code in leafmap/plotlymap.py
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
def set_layer_visibility(self, name: str, show: Optional[bool] = True) -> None:
    """Sets the visibility of a layer.

    Args:
        name (str): Name of the layer to set.
        show (bool, optional): If True, shows the layer. Defaults to True.
    """

    if name in self.get_tile_layers():
        index = self.find_layer_index(name)
        self.layout.mapbox.layers[index].visible = show
    elif name in self.get_data_layers():
        index = self.find_layer_index(name)
        self.data[index].visible = show
    else:
        print(f"Layer {name} not found.")

show(toolbar=True, map_min_width='91%', map_max_width='98%', refresh=False, **kwargs)

Shows the map.

Parameters:

Name Type Description Default
toolbar bool

Whether to show the toolbar. Defaults to True.

True
map_min_width str

The minimum width of the map. Defaults to '91%'.

'91%'
map_max_width str

The maximum width of the map. Defaults to '98%'.

'98%'
refresh bool

Whether to refresh the map when the map is resized. Defaults to False.

False

Returns:

Name Type Description
Canvas None

Map canvas.

Source code in leafmap/plotlymap.py
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def show(
    self,
    toolbar: Optional[bool] = True,
    map_min_width: Optional[str] = "91%",
    map_max_width: Optional[str] = "98%",
    refresh: Optional[bool] = False,
    **kwargs,
) -> None:
    """Shows the map.

    Args:
        toolbar (bool, optional): Whether to show the toolbar. Defaults to True.
        map_min_width (str, optional): The minimum width of the map. Defaults to '91%'.
        map_max_width (str, optional): The maximum width of the map. Defaults to '98%'.
        refresh (bool, optional): Whether to refresh the map when the map is resized. Defaults to False.

    Returns:
        Canvas: Map canvas.
    """
    if not toolbar:
        super().show(**kwargs)
    else:
        canvas = Canvas(
            self,
            map_min_width=map_min_width,
            map_max_width=map_max_width,
            map_refresh=refresh,
        )
        return canvas.canvas

fix_widget_error()

Fix FigureWidget - 'mapbox._derived' Value Error. Adopted from: https://github.com/plotly/plotly.py/issues/2570#issuecomment-738735816

Source code in leafmap/plotlymap.py
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
def fix_widget_error() -> None:
    """
    Fix FigureWidget - 'mapbox._derived' Value Error.
    Adopted from: https://github.com/plotly/plotly.py/issues/2570#issuecomment-738735816
    """
    import shutil
    import importlib.resources

    pkg_dir = os.path.dirname(importlib.resources.files("plotly") / "plotly.py")

    basedatatypesPath = os.path.join(pkg_dir, "basedatatypes.py")

    backup_file = basedatatypesPath.replace(".py", "_bk.py")
    shutil.copyfile(basedatatypesPath, backup_file)

    # read basedatatypes.py
    with open(basedatatypesPath, "r") as f:
        lines = f.read()

    find = "if not BaseFigure._is_key_path_compatible(key_path_str, self.layout):"

    replace = """if not BaseFigure._is_key_path_compatible(key_path_str, self.layout):
                if key_path_str == "mapbox._derived":
                    return"""

    # add new text
    lines = lines.replace(find, replace)

    # overwrite old 'basedatatypes.py'
    with open(basedatatypesPath, "w") as f:
        f.write(lines)