Part 3 - Visualizing spatial data on the map widget

First, to use the map widget, call gis.map() and assign it to a variable that you can then query to bring up the widget in the notebook:

import arcgis
from arcgis.gis import GIS
# Create a GIS object, as an anonymous user for this example
gis = GIS()
# Create a map widget
map1 = gis.map('USA') # Passing a place name to the constructor
                        # will initialize the extent of the map.
map1

Adding single layer

Adding Web Layer to the map

You can add a number of different layer objects, such as FeatureLayer, FeatureCollection, ImageryLayer, or MapImageLayer, to the map. For instance, you can use the following cell to add a FeatureLayer:

world_countries_item = gis.content.get('ac80670eb213440ea5899bbf92a04998')
world_countries_layer = world_countries_item.layers[0]
world_countries_layer
<FeatureLayer url:"https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/World_Countries/FeatureServer/0">
map1.content.add(world_countries_layer, options={'opacity':0.4})

Similar to FeatureLayers, you can also add ImageryLayers items. You can also specify either a built-in raster function or a custom one for rendering.

map2 = gis.map('USA') # Passing a place name to the constructor
                        # will initialize the extent of the map.
map2
landsat_item = GIS().content.search("Landsat 8 Views", "Imagery Layer", max_items=2)[0]
landsat_item
Pansharpened Landsat
Landsat 8 and 9 pansharpened and multitemporal 15m imagery rendered on-the-fly as Natural Color with DRA for visualization and analysis. It is updated daily with new imagery directly sourced from the USGS Landsat collection on AWS.
Imagery Layer by esri
Last Modified: August 24, 2022
1 comments, 429,412 views
map2.content.add(landsat_item)

To zoom to one or more layers, call the zoom_to_layer() method and pass a layer or list of layers that you want to snap your map to. The supplied item can be a single instance or a list of an Item, Layer, DataFrame, FeatureSet, or FeatureCollection.

The code below shows how to zoom to a single layer:

map2.content.add(landsat_item)
map2.zoom_to_layer(landsat_item)
map3 = gis.map('USA') # Passing a place name to the constructor
                        will initialize the extent of the map.
map3
prep_item = GIS().content.search("Precipitation", "Map Image Layer", max_items=2)[1]
prep_item
U.S. Historical Precipitation Trends 1985 to 2010
Historical precipitation trends from 1895 to 2010. Precipitation is shown as percent annual precipitation change per century. Results are based on weather station data.
Map Image Layer by DSCGIS
Last Modified: May 26, 2020
0 comments, 5,564 views
prep_layer = prep_item.layers[1]
prep_layer
<MapRasterLayer url:"https://tiles.arcgis.com/tiles/fBc8EJBxQRMcHlei/arcgis/rest/services/U_S__Historical_Precipitation_Trends_1985_to_2010/MapServer/1">
map3.content.add(prep_item)
map3.zoom_to_layer(prep_layer)

Adding local and in-memory layers to the map

Add a Spatially-Enabled Data Frame (SeDF)

We can read census data on major cities and load the data into a Spatially Enabled DataFrame (SeDF), which will then allow us to visualize the points by calling the plot() method off the SeDF's spatial accessor and passing the map you created to it.

# create an anonymous connection to ArcGIS Online and get a public item
census_item = gis.content.get("85d0ca4ea1ca4b9abf0c51b9bd34de2e")
census_flayer = census_item.layers[0]

# Specify a SQL query and get a sub-set of the original data as a DataFrame
census_df = census_flayer.query(where="AGE_45_54 < 450").sdf

# Visualize the top 5 records
census_df.head()
FIDNAMECLASSSTSTFIPSPLACEFIPSCAPITALPOP_CLASSPOPULATIONPOP2010...MARHH_NO_CMHH_CHILDFHH_CHILDFAMILIESAVE_FAM_SZHSE_UNITSVACANTOWNER_OCCRENTER_OCCSHAPE
0306Purdue UniversityCensus Designated PlaceIN18186238861236512183...2449234912.66136210441254{"x": -9676280.259129459, "y": 4928486.7435240...
1600StanfordCensus Designated PlaceCA06067390661517913809...689133212302.773999867903123{"x": -13599607.21449169, "y": 4498534.6279709...
2682Fort CarsonCensus Designated PlaceCO08082737061389113813...3193942123193.592629180152434{"x": -11664455.032700792, "y": 4684537.534384...
3742StorrsCensus Designated PlaceCT09097398061556915344...27614184892.691737166592979{"x": -8043406.213645851, "y": 5131741.8140288...
41035Camp Pendleton SouthCensus Designated PlaceCA06061056161045010616...3893716925003.692865296112558{"x": -13066535.250599463, "y": 3925680.810605...

5 rows × 50 columns

map4 = GIS().map("United States")
map4
map4.zoom = 4
map4.center = [39,-98]
census_df.spatial.plot(map_widget= map4)
True

Add an in-memory FeatureSet

Besides adding in the the SeDF, we can also add a FeatureSet. For example, below we will search for the USA freeway layer and visualize it by adding it to the map widget as a FeatureSet object returned by the query method. Once added, we then draw it with default line symbols.

freeway_item = gis.content.search('title:USA Freeway System AND owner:esri_dm', 
                                   item_type = 'Feature Layer')[0]
freeway_item
USA Freeway System
This layer presents rural and urban interstate highways.
Feature Layer Collection by esri_dm
Last Modified: February 06, 2023
5 comments, 5,479,816 views
freeway_sdf = freeway_item.layers[0]
freeway_fset = freeway_sdf.query(where="DIST_KM>2800", as_df=False)
freeway_fset
<FeatureSet> 7 features
map5 = gis.map('USA')
map5
map5.zoom = 6
map5.center = [39,-98]
map5.content.add(freeway_fset, options={'opacity':0.75})

Adding a local raster

A local raster can be read into the map widget as a numpy array with arcgis.raster imported on the machine.

Note: Local raster can only be loaded for display when `arcpy` is installed on the current environment.
import numpy
import matplotlib.pyplot as plt
from arcgis.raster import Raster
map6 = GIS().map("Newark, NJ")
map6
raster = Raster(r'../../static/img/newark_nj_1922.jpg',
                extent = {"xmin":-74.22655,
                          "ymin":40.712216,
                          "xmax":-74.12544,
                          "ymax":40.773941,
                          "spatialReference":{"wkid":4326}},
               opacity = 0.85)
map6.content.add(raster)

To immediately release the in-app memory immediate, run the follow cell to remove the raster layer:

map6.content.remove(0)
True

Other operations

Drawing graphics and geometries

Draw geometries

map7 = gis.map("Port of Long Beach")
map7.basemap.basemap = "satellite"
map7

When it comes to adding geometries, we can either create a geometry object and use the draw method to apply the object onto our display, or we can input point, polyline, or polygon as keywords in the draw() method, which will then trigger a user interactive drawing session on the widget.

map7.zoom = 6
from arcgis.geometry import Geometry

pt = Geometry({"x" : -118.15, "y" : 33.80, 
            "spatialReference" : {"wkid" : 4326}})
map7.content.draw(pt)
line = Geometry({
    "paths":[
        [[-118.38, 33.82], [-118.38, 33.92], [-118.18, 33.92]]
    ],
    "spatialReference":{"wkid":4326}
})
map7.content.draw(line)
polygon = Geometry({
    "rings":[
        [[-118.38, 33.82], [-118.38, 33.92], [-118.18, 33.92], [-118.18, 33.82]]
    ],
    "spatialReference":{"wkid":4326}
})
map7.content.draw(polygon)

Draw with symbols and pop-ups

The draw() method can be used to draw a deterministic shape on the map widget when the input shape is a known Geometry object, a list of coordinate pairs, a FeatureSet, or a dict object that represents a geometry. The other way to use draw is to provide users with an interactive sketch and display experience when the input shape is one of the expected strings, e.g. "circle", "ellipse", "Polygon", "Polyline", "MultiPoint", "Point", "rectangle", "triangle".

draw(shape, popup=None, symbol=None, attributes=None)
# The draw method draws a shape on the map widget.

Note: Anything can be drawn from known Geometry objects, coordinate pairs, and FeatureSet objects.

The shape argument can be one of the below objects. See draw() for details:

  • Known Geometry objects: Shape is one of the following: circle, ellipse, Polygon, Polyline, MultiPoint, Point, rectangle, triangle.
  • Coordinate pair: specified shape as a list of [lat, long]. Eg: [34, -81]
  • FeatureSet: shape can be a FeatureSet object.
  • Dict object representing a geometry.

The popup parameter is optional, and if it used, it must be a dict containing title and content as keys that will be displayed when the shape is clicked. In the case of a FeatureSet, title and content are names of attributes of the features in the FeatureSet, rather than actual string values for title and content.

The symbol parameter is also optional, and if it is used, it should be a dict object. See the Symbol Objects page in the ArcGIS REST API documentation for more information. A default symbol is used if one is not specified. A helper utility to get the symbol format for several predefined symbols is available within the Esri symbol selector.

The attributes parameter is again optional, and if it is used, it should be a dict object that specifies a dict containing name value pairs of fields and field values associated with the graphic.

The examples we have seen so far have not been applied with customized symbols and pop-ups. Next, let's follow a quick example that visualizes a predefined Point object with the symbol parameter and draws the nearby hospitals with customized symbols and a self-defined pop-up:

from arcgis.gis import GIS
map7b = GIS().map("Port of Long Beach")
map7b.basemap.basemap ='gray-vector'
map7b
map7b.zoom
15.0
from arcgis.map.symbols import PictureMarkerSymbolEsriPMS
from arcgis.map.popups import PopupInfo

star_symbol = PictureMarkerSymbolEsriPMS(**{"angle":0,"xoffset":0,"yoffset":0,"type":"esriPMS",
                "url":"http://static.arcgis.com/images/Symbols/Shapes/RedStarLargeB.png",
                "contentType":"image/png","width":24,"height":24})
map7b.content.draw(pt, symbol=star_symbol)

Now, let's use the geocode method to find a list of 10 hospitals near the defined Point object:

from arcgis.geocoding import geocode
hospitals = geocode('hospital', location=[-118.15, 33.80], max_locations=10)
len(hospitals)
10
hospitals[0]['attributes']['X']
-118.145887142854
hospital_symbol = PictureMarkerSymbolEsriPMS(angle = 0, xoffset = 0, yoffset = 0,
                   url = "http://static.arcgis.com/images/Symbols/SafetyHealth/Hospital.png",
                   content_type = "image/png", width = 24, height = 24)
hospital_symbol.type = "esriPMS"


for place in hospitals:
    popup= PopupInfo(**{"title" : place['attributes']['PlaceName'], 
           "description" : place['attributes']['Place_addr']})
    location = Geometry({"x" : place['attributes']['X'], "y" : place['attributes']['Y'], 
            "spatialReference" : {"wkid" : 4326}})
    map7b.content.draw(location, symbol=hospital_symbol, popup=popup)

Draw sketches interactively

You can draw or sketch graphics on the map interactively using the draw() method. For instance, you can draw and annotate rectangles, ellipses, arrow marks, etc. as shown below:

usa_map = GIS().map("USA")
usa_map
# create rectangle geometry
from arcgis.geometry import Geometry
usa_polygon = Geometry({
    "rings" : [[[-131, 55], [-131, 20], [-63, 20], [-63, 55]]],
    "spatialReference" : {"wkid" : 4326}
})
usa_map.content.draw(usa_polygon)
usa_map.zoom = 3
usa_map.center = [39,-98]

If the graphics are no longer needed, you can use the .content.remove() method to remove them.

usa_map.content.remove(0)
True

Customizing layer symbology

While calling the .content.add() method, you can specify a set of renderer instructions as a dictionary to the options parameter. You have seen how to set the transparency for a layer in previous cells. The opacity value ranges from 0 - 1, with 0 being fully transparent and 1 being fully opaque.

You can make use of the "smart mapping" capability to render feature layers with symbology that varies based on an attribute field of that layer. The cell below adds the "USA Freeway System" layer to the map and changes the width of the line segments based on the length of the freeway. Unlike in map5 where freeways are classified in sizes, here you will see freeways classified in colors. For more, checkout smart mapping.

map5b = gis.map('USA')
map5b
map5b.zoom = 4
map5b.center = [39,-98]
map5b.content.add(freeway_fset, options={'opacity':0.9})
sm_manager = map5b.content.renderer(0).smart_mapping()
sm_manager.class_breaks_renderer(break_type='color', field="DIST_KM")

Querying layers in a map

You can list the layers added to the map using the content.layers property.

map1.content.layers
[<FeatureLayer url:"https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/World_Countries/FeatureServer/0">]
map5.content.layers
[<FeatureCollection>]

Removing layers in a map

To remove one or more layers, call the .content.remove() method and pass a list of layers that you want removed. To get a list of valid layers that can be removed, call the .content.layers property as shown in the previous cell.

The code below shows how to remove the USA freeways layer:

map1.content.remove(0)
True

Viewing legend

Enable the display of a legend on the map widget by setting the boolean to True:

map5b.legend.enabled = True

Finally, you can turn the legend display off when it no longer needed by executing the following cell:

map5b.legend.enabled = False

Conclusion

In Part 3 of this guide series, we have explored how to add single layers (Web Layer, local raster, or an in-memory SeDF) to a map, how to draw graphics and geometries, and how to perform other visualization operations. In the next chapter, we will explore how to display time-enabled data, the nature of drawing with the ArcGIS API for Javascript, and the best practices when rendering a large number of layers in a single map widget.

Back to Top

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.