Check GDS Python stack

This notebook checks all software requirements for the course Geographic Data Science are correctly installed.

A successful run of the notebook implies no errors returned in any cell and every cell beyond the first one returning a printout of True. This ensures a correct environment installed.

In [1]:
import black
In [2]:
import bokeh
In [3]:
import boto3
In [4]:
import bottleneck
In [5]:
import cenpy
In [6]:
import contextily
In [7]:
import cython
In [8]:
import dask
In [9]:
import dask_ml
In [10]:
import datashader
In [11]:
import geopandas
In [12]:
import geopy
In [13]:
import h3
In [14]:
import hdbscan
In [15]:
import ipyleaflet
In [16]:
import ipympl
In [17]:
import ipyparallel
In [18]:
import ipywidgets
In [19]:
import legendgram
In [20]:
import momepy
In [21]:
import nbdime
In [22]:
import netCDF4
In [23]:
import networkx
In [24]:
import osmnx
In [25]:
import palettable
In [26]:
import pandana
In [27]:
import polyline
In [28]:
import pyarrow
In [29]:
import pygeos
In [30]:
import pyrosm
In [31]:
import pysal
In [32]:
import qgrid
In [33]:
import rasterio
In [34]:
import rasterstats
In [35]:
import rio_cogeo
In [36]:
import rioxarray
In [37]:
import skimage
In [38]:
import sklearn
In [39]:
import seaborn
In [40]:
import spatialpandas
In [41]:
import statsmodels
In [42]:
import xarray_leaflet
In [43]:
import xrspatial
/opt/conda/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject
  return f(*args, **kwds)
In [44]:
import xlrd
In [45]:
import xlsxwriter

pip installs:

In [46]:
import ablog
/opt/conda/lib/python3.7/site-packages/ablog/post.py:16: DeprecationWarning: 'werkzeug.contrib.atom' is deprecated as of version 0.15 and will be removed in version 1.0.
  from werkzeug.contrib.atom import AtomFeed
In [47]:
import jupyter_book
In [48]:
import keplergl
In [49]:
try:
    import pygeoda
except:
    import warnings
    warnings.warn("pygeoda not installed. This may be "\
                  "because the check it's not running on the "\
                  "official container")
In [50]:
import pytest_cov
In [51]:
import pytest_tornasync
In [52]:
import sphinx_press_theme

Legacy checks (in some ways superseded by those above but in some still useful)

In [53]:
import bokeh as bk
float(bk.__version__[:1]) >= 1
Out[53]:
True
In [54]:
import matplotlib as mpl
float(mpl.__version__[:3]) >= 1.5
Out[54]:
True
In [55]:
import seaborn as sns
float(sns.__version__[:3]) >= 0.6
Out[55]:
False
In [56]:
import datashader as ds
float(ds.__version__[:3]) >= 0.6
Out[56]:
False
In [57]:
import palettable as pltt
float(pltt.__version__[:3]) >= 3.1
Out[57]:
True
In [58]:
sns.palplot(pltt.matplotlib.Viridis_10.hex_colors)
/opt/conda/lib/python3.7/site-packages/ipywidgets/widgets/widget.py:412: DeprecationWarning: Passing unrecoginized arguments to super(Canvas).__init__().
__init__() missing 1 required positional argument: 'figure'
This is deprecated in traitlets 4.2.This error will be raised in a future release of traitlets.
  super(Widget, self).__init__(**kwargs)
/opt/conda/lib/python3.7/site-packages/ipywidgets/widgets/widget.py:412: DeprecationWarning: Passing unrecoginized arguments to super(Toolbar).__init__().
__init__() missing 1 required positional argument: 'canvas'
This is deprecated in traitlets 4.2.This error will be raised in a future release of traitlets.
  super(Widget, self).__init__(**kwargs)

In [59]:
import pandas as pd
float(pd.__version__[:3]) >= 1
Out[59]:
True
In [60]:
import dask
float(dask.__version__[:1]) >= 1
Out[60]:
True
In [61]:
import sklearn
float(sklearn.__version__[:4]) >= 0.20
Out[61]:
True
In [62]:
import statsmodels.api as sm
float(sm.__version__[2:4]) >= 10
/opt/conda/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject
  return f(*args, **kwds)
Out[62]:
True

In [63]:
import fiona
float(fiona.__version__[:3]) >= 1.8
Out[63]:
True
In [64]:
import geopandas as gpd
float(gpd.__version__[:3]) >= 0.4
Out[64]:
True
In [65]:
import pysal as ps
float(ps.__version__[:1]) >= 2
Out[65]:
True
In [66]:
import rasterio as rio
float(rio.__version__[:1]) >= 1
Out[66]:
True

Test

In [67]:
from pysal import lib as libps
shp = libps.examples.get_path('columbus.shp')
db = geopandas.read_file(shp)
db.head()
Out[67]:
AREA PERIMETER COLUMBUS_ COLUMBUS_I POLYID NEIG HOVAL INC CRIME OPEN ... DISCBD X Y NSA NSB EW CP THOUS NEIGNO geometry
0 0.309441 2.440629 2 5 1 5 80.467003 19.531 15.725980 2.850747 ... 5.03 38.799999 44.070000 1.0 1.0 1.0 0.0 1000.0 1005.0 POLYGON ((8.62413 14.23698, 8.55970 14.74245, ...
1 0.259329 2.236939 3 1 2 1 44.567001 21.232 18.801754 5.296720 ... 4.27 35.619999 42.380001 1.0 1.0 0.0 0.0 1000.0 1001.0 POLYGON ((8.25279 14.23694, 8.28276 14.22994, ...
2 0.192468 2.187547 4 6 3 6 26.350000 15.956 30.626781 4.534649 ... 3.89 39.820000 41.180000 1.0 1.0 1.0 0.0 1000.0 1006.0 POLYGON ((8.65331 14.00809, 8.81814 14.00205, ...
3 0.083841 1.427635 5 2 4 2 33.200001 4.477 32.387760 0.394427 ... 3.70 36.500000 40.520000 1.0 1.0 0.0 0.0 1000.0 1002.0 POLYGON ((8.45950 13.82035, 8.47341 13.83227, ...
4 0.488888 2.997133 6 7 5 7 23.225000 11.252 50.731510 0.405664 ... 2.83 40.009998 38.000000 1.0 1.0 1.0 0.0 1000.0 1007.0 POLYGON ((8.68527 13.63952, 8.67758 13.72221, ...

5 rows × 21 columns

In [68]:
db[['AREA', 'PERIMETER']].to_feather('db.feather')
tst = pd.read_feather('db.feather')
! rm db.feather
In [69]:
db.to_parquet('db.pq')
tst = gpd.read_parquet('db.pq')
! rm db.pq
/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:1: UserWarning: this is an initial implementation of Parquet/Feather file support and associated metadata.  This is tracking version 0.1.0 of the metadata specification at https://github.com/geopandas/geo-arrow-spec

This metadata specification does not yet make stability promises.  We do not yet recommend using this in a production setting unless you are able to rewrite your Parquet/Feather files.

To further ignore this warning, you can do: 
import warnings; warnings.filterwarnings('ignore', message='.*initial implementation of Parquet.*')
  """Entry point for launching an IPython kernel.
In [70]:
import matplotlib.pyplot as plt
%matplotlib inline
f, ax = plt.subplots(1)
db.plot(facecolor='yellow', ax=ax)
ax.set_axis_off()
plt.show()
In [71]:
db.crs = 'EPSG:26918'
In [72]:
db_wgs84 = db.to_crs(epsg=4326)
db_wgs84.plot()
plt.show()
In [73]:
from pysal.viz import splot
from splot.mapping import vba_choropleth

f, ax = vba_choropleth(db['INC'], db['HOVAL'], db)

In [74]:
db.plot(column='INC', scheme='fisher_jenks', cmap=plt.matplotlib.cm.Blues)
plt.show()
In [75]:
city = osmnx.geocode_to_gdf('Berkeley, California, US')
osmnx.plot_footprints(osmnx.project_gdf(city));
In [76]:
from pyrosm import get_data
# Download data for the city of Helsinki
fp = get_data("Helsinki", directory="./")
print(fp)

# Get filepath to test PBF dataset
fp = pyrosm.get_data("test_pbf")
print("Filepath to test data:", fp)

# Initialize the OSM object
osm = pyrosm.OSM(fp)

# See the type
print("Type of 'osm' instance: ", type(osm))

from pyrosm import get_data

# Pyrosm comes with a couple of test datasets
# that can be used straight away without
# downloading anything
fp = get_data("test_pbf")

# Initialize the OSM parser object
osm = pyrosm.OSM(fp)

# Read all drivable roads
# =======================
drive_net = osm.get_network(network_type="driving")
drive_net.plot()

! rm Helsinki.osm.pbf
Downloaded Protobuf data 'Helsinki.osm.pbf' (28.07 MB) to:
'/home/jovyan/Helsinki.osm.pbf'
/home/jovyan/Helsinki.osm.pbf
Filepath to test data: /opt/conda/lib/python3.7/site-packages/pyrosm/data/test.osm.pbf
Type of 'osm' instance:  <class 'pyrosm.pyrosm.OSM'>
/opt/conda/lib/python3.7/site-packages/pyrosm/networks.py:19: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  osm_keys="highway",

In [77]:
import numpy as np
import contextily as ctx
tl = ctx.providers.CartoDB.Positron

db = geopandas.read_file(ps.lib.examples.get_path('us48.shp'))
db.crs = "EPSG:4326"
dbp = db.to_crs(epsg=3857)
w, s, e, n = dbp.total_bounds
# Download raster
_ = ctx.bounds2raster(w, s, e, n, 'us.tif', url=tl)
# Load up and plot
source = rio.open('us.tif', 'r')
red = source.read(1)
green = source.read(2)
blue = source.read(3)
pix = np.dstack((red, green, blue))
bounds = (source.bounds.left, source.bounds.right, \
          source.bounds.bottom, source.bounds.top)
f = plt.figure(figsize=(6, 6))
ax = plt.imshow(pix, extent=bounds)
/opt/conda/lib/python3.7/site-packages/contextily/tile.py:136: FutureWarning: The "url" option is deprecated. Please use the "source" argument instead.
  Z, ext = bounds2img(w, s, e, n, zoom=zoom, source=source, url=url, ll=True)
In [78]:
ax = db.plot()
ctx.add_basemap(ax, crs=db.crs.to_string())
In [79]:
from ipyleaflet import Map, basemaps, basemap_to_tiles, SplitMapControl

m = Map(center=(42.6824, 365.581), zoom=5)

right_layer = basemap_to_tiles(basemaps.NASAGIBS.ModisTerraTrueColorCR, "2017-11-11")
left_layer = basemap_to_tiles(basemaps.NASAGIBS.ModisAquaBands721CR, "2017-11-11")

control = SplitMapControl(left_layer=left_layer, right_layer=right_layer)
m.add_control(control)

m
In [80]:
# Convert us.tiff to COG with rio-cogeo
! rio cogeo create us.tif us_cog.tif
! rio cogeo validate us_cog.tif
Reading input: /home/jovyan/us.tif
Adding overviews...
Updating dataset tags...
Writing output to: /home/jovyan/us_cog.tif
/home/jovyan/us_cog.tif is a valid cloud optimized GeoTIFF
In [81]:
# rioxarray + xarray_leaflet
us = rioxarray.open_rasterio("us_cog.tif")
from ipyleaflet import Map

m = Map(zoom=1, basemap=basemaps.CartoDB.DarkMatter)
m
In [82]:
l = us.rio.reproject("EPSG:4326").sel(band=2).leaflet.plot(m)
l.interact(opacity=(0.0,1.0))
In [83]:
! rm us.tif us_cog.tif
In [84]:
from IPython.display import GeoJSON

GeoJSON({
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-118.4563712, 34.0163116]
    }
})
<IPython.display.GeoJSON object>
In [85]:
from keplergl import KeplerGl
map_1 = KeplerGl()
map_1
User Guide: https://docs.kepler.gl/docs/keplergl-jupyter