Landcover in Malawi (2010) by Malawi Spatial Data Platform (MASDAP)

Data were obtained from the ArcGIS Hub and provide details of the various types of land cover in Malawi.

This is an example of how to use plotly express and choropleth mapbox to plot geospatial data.

In [1]:
# import geojson file from ArcGIS Open Data Hub
from urllib.request import urlopen
import json
with urlopen('https://opendata.arcgis.com/datasets/7533fe68b047461ea6187841c706375b_3.geojson') as response:
    malawi = json.load(response)

# print first 10 features
malawi["features"][10]
Out[1]:
{'type': 'Feature',
 'properties': {'OBJECTID': 11,
  'HECTARES': 296.459295,
  'KM_SQ': 2.964593,
  'NAME': 'Forest'},
 'geometry': {'type': 'Polygon',
  'coordinates': [[[33.1649742126063, -9.54224959828515],
    [33.1610258679993, -9.53796421889459],
    [33.1582951928119, -9.53432946592335],
    [33.1558860059784, -9.53186132430869],
    [33.1542966335475, -9.52752957592284],
    [33.152052674898, -9.52378601629898],
    [33.1497384375505, -9.52004247086129],
    [33.150277710046, -9.51741924713086],
    [33.1524564676844, -9.51617011996177],
    [33.1552118621549, -9.51825825426329],
    [33.1563748848277, -9.52117920449754],
    [33.1578443930289, -9.52305986018157],
    [33.1594716201439, -9.52239885019041],
    [33.1623761277221, -9.52048905909574],
    [33.1648380386703, -9.52016229229222],
    [33.1663866243772, -9.52356239894159],
    [33.1669336641857, -9.52780414373344],
    [33.1667081514849, -9.53073476275453],
    [33.1672858877642, -9.5342438627715],
    [33.1692183203075, -9.53805982807179],
    [33.170202568667, -9.54012155857237],
    [33.1688615753632, -9.54219346605507],
    [33.1649742126063, -9.54224959828515]]]}}
In [2]:
# import df with same object ID from ArcGIS server
import pandas as pd
df = pd.read_csv("Malawi_2016.csv",
                   dtype={"NAME": str})

import geopandas as gpd
# load plotly express
import plotly.express as px

# print head of df
df.head(10)
Out[2]:
OBJECTID HECTARES KM_SQ NAME
0 1 1.663199e+04 166.319914 Forest
1 2 1.518405e+05 1518.405066 Agriculture in forest area
2 3 3.866132e+03 38.661317 Agriculture in forest area
3 4 8.163614e+01 0.816361 Dambo area/agriculture
4 5 1.712681e+01 0.171268 Forest
5 6 1.064963e+04 106.496266 Forest
6 7 2.271888e+06 22718.877231 Water surface
7 8 2.061306e+02 2.061306 Dambo area/agriculture
8 9 4.224788e+02 4.224788 Dambo area/agriculture
9 10 2.035598e+02 2.035598 Forest
In [3]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1785 entries, 0 to 1784
Data columns (total 4 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   OBJECTID  1785 non-null   int64  
 1   HECTARES  1785 non-null   float64
 2   KM_SQ     1785 non-null   float64
 3   NAME      1785 non-null   object 
dtypes: float64(2), int64(1), object(1)
memory usage: 55.9+ KB
In [4]:
# plot histogram of type of landcover
import plotly.graph_objects as go
fig = px.pie(df, values = "OBJECTID", names="NAME", title = "Type of land cover in Malawi (MASDAP 2010)")
fig = go.FigureWidget(fig)
fig
In [5]:
# plot histogram of sum hectare per land use area
fig = px.histogram(df, x="NAME", y="HECTARES").update_xaxes(categoryorder="total descending")
fig.update_layout(
    title={
        'text': "Sum of hectares per land use area (MASDAP 2010)",
        'y':0.95,
        'x':0.5,
        'xanchor': 'center',
        'yanchor': 'top'})
fig.update_yaxes(showgrid=False)  # turning off the grid
fig = go.FigureWidget(fig)
fig
In [6]:
# plot choropleth mapbox with plotly express using geojson and df data 
import plotly.graph_objs as go
fig = px.choropleth_mapbox(df, geojson=malawi, color="HECTARES",
                           locations="HECTARES", featureidkey="properties.HECTARES",
                           center={"lat": -13.254308, "lon": 34.301525},
                           mapbox_style="carto-positron", zoom=9,
                           labels={'HECTARES':'Hectares'})
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig = go.FigureWidget(fig)
fig
In [7]:
# subset data to only show values for Dambo area/agriculture & Forest
df_subset = df[df.NAME.isin(["Dambo area/agriculture", "Forest", "Agriculture/settlement", "Forest Plantation"])]
print(df_subset.head(10))
    OBJECTID      HECTARES       KM_SQ                    NAME
0          1  16631.991369  166.319914                  Forest
3          4     81.636141    0.816361  Dambo area/agriculture
4          5     17.126809    0.171268                  Forest
5          6  10649.626613  106.496266                  Forest
7          8    206.130620    2.061306  Dambo area/agriculture
8          9    422.478836    4.224788  Dambo area/agriculture
9         10    203.559777    2.035598                  Forest
10        11    296.459295    2.964593                  Forest
11        12    207.502842    2.075028                  Forest
12        13   4289.949828   42.899498                  Forest
In [8]:
# plot choropleth mapbox with plotly express using geojson and df data 
fig = px.choropleth_mapbox(df_subset, geojson=malawi, color="NAME",
                           locations="HECTARES", featureidkey="properties.HECTARES",
                           center={"lat": -13.254308, "lon": 34.301525},
                           mapbox_style="carto-positron", zoom=9,
                           labels={'NAME':'Land cover'})
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig