Composition of signatures within TTWA boundaries

import geopandas
import pandas
import tobler

tobler.__version__
'0.9.0'

https://services1.arcgis.com/ESMARspQHYMw9BZ9/ArcGIS/rest/services/TTWA_2011_UK/FeatureServer

url = "https://services1.arcgis.com/ESMARspQHYMw9BZ9/arcgis/rest/services/TTWA_2011_UK/FeatureServer/0/query?where=1%3D1&objectIds=&time=&geometry=&geometryType=esriGeometryPolygon&inSR=&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&returnGeodetic=false&outFields=&returnGeometry=true&returnCentroid=false&featureEncoding=esriDefault&multipatchOption=xyFootprint&maxAllowableOffset=&geometryPrecision=&outSR=&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnQueryGeometry=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=pgeojson&token="
ttwa = geopandas.read_file(url)
ttwa
TTWA11CD geometry
0 E30000004 POLYGON ((-1.34865 53.58333, -1.32673 53.55813...
1 E30000018 POLYGON ((-1.93086 53.95027, -1.89833 53.92398...
2 E30000029 POLYGON ((-1.73679 53.70811, -1.73128 53.68037...
3 E30000039 POLYGON ((-2.00451 54.17288, -1.99254 54.15528...
4 E30000046 POLYGON ((-2.26489 50.75912, -2.24239 50.75563...
... ... ...
223 W22000030 MULTIPOLYGON (((-4.77992 52.76561, -4.80242 52...
224 W22000031 POLYGON ((-3.14509 53.26082, -3.17735 53.24382...
225 W22000032 POLYGON ((-3.47007 51.82850, -3.47633 51.80947...
226 W22000033 POLYGON ((-3.48307 52.86552, -3.50541 52.84191...
227 W22000034 POLYGON ((-2.72684 52.98327, -2.73532 52.97002...

228 rows × 2 columns

# drop NI
ttwa = ttwa[~ttwa.TTWA11CD.str.startswith("N")]
ttwa.plot()
<AxesSubplot:>
../_images/ttwa_7_1.png
ttwa.to_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa.pq")
<ipython-input-30-01f59cdfba9b>: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.*')
  ttwa.to_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa.pq")
ttwa = geopandas.read_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa.pq")
signatures = geopandas.read_parquet("../../urbangrammar_samba/spatial_signatures/signatures/signatures_combined_levels_simplified.pq")
# drop an outlier island
signatures = signatures.drop(96691)
types = {
    "0_0": "Countryside agriculture",
    "1_0": "Accessible suburbia",
    "3_0": "Open sprawl",
    "4_0": "Wild countryside",
    "5_0": "Warehouse/Park land",
    "6_0": "Gridded residential quarters",
    "7_0": "Urban buffer",
    "8_0": "Disconnected suburbia",
    "2_0": "Dense residential neighbourhoods",
    "2_1": "Connected residential neighbourhoods",
    "2_2": "Dense urban neighbourhoods",
    "9_0": "Local urbanity",
    "9_1": "Concentrated urbanity",
    "9_2": "Regional urbanity",
    "9_4": "Metropolitan urbanity",
    "9_5": "Hyper concentrated urbanity",
}

signatures["signature_type"] = signatures["signature_type"].map(types)
signatures = signatures[["signature_type", "geometry"]].dropna()
signatures
signature_type geometry
0 Countryside agriculture POLYGON ((62219.999 798499.999, 62109.999 7985...
1 Countryside agriculture POLYGON ((63507.682 796515.168, 63471.096 7965...
2 Countryside agriculture POLYGON ((65953.174 802246.171, 65523.864 8023...
3 Countryside agriculture POLYGON ((67297.740 803435.799, 67220.290 8034...
4 Countryside agriculture POLYGON ((75760.000 852669.999, 75699.999 8527...
... ... ...
96686 Hyper concentrated urbanity POLYGON ((528530.169 181095.720, 528544.721 18...
96687 Hyper concentrated urbanity POLYGON ((528602.733 181135.451, 528572.629 18...
96688 Hyper concentrated urbanity POLYGON ((528643.907 181217.443, 528632.000 18...
96689 Hyper concentrated urbanity POLYGON ((528734.583 181316.821, 528722.252 18...
96690 Hyper concentrated urbanity POLYGON ((530336.433 181039.754, 530301.430 18...

96688 rows × 2 columns

%%time
interpolated = tobler.area_weighted.area_interpolate(signatures, ttwa.to_crs(signatures.crs), categorical_variables=["signature_type"], n_jobs=-1)
CPU times: user 5.63 s, sys: 304 ms, total: 5.93 s
Wall time: 56.2 s
interpolated.columns = [c[15:] if c != "geometry" else c for c  in interpolated.columns]
interpolated = interpolated[~interpolated.geometry.isna()]
interpolated["TTWA11CD"] = ttwa.TTWA11CD.values
import pandas

names = pandas.read_csv("https://opendata.arcgis.com/api/v3/datasets/9ac894d3086641bebcbfa9960895db39_0/downloads/data?format=csv&spatialRefId=4326")
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
/tmp/ipykernel_420209/3679243829.py in <module>
      1 import pandas
      2 
----> 3 names = pandas.read_csv("https://opendata.arcgis.com/api/v3/datasets/9ac894d3086641bebcbfa9960895db39_0/downloads/data?format=csv&spatialRefId=4326")

/opt/conda/lib/python3.9/site-packages/pandas/util/_decorators.py in wrapper(*args, **kwargs)
    309                     stacklevel=stacklevel,
    310                 )
--> 311             return func(*args, **kwargs)
    312 
    313         return wrapper

/opt/conda/lib/python3.9/site-packages/pandas/io/parsers/readers.py in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, error_bad_lines, warn_bad_lines, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options)
    584     kwds.update(kwds_defaults)
    585 
--> 586     return _read(filepath_or_buffer, kwds)
    587 
    588 

/opt/conda/lib/python3.9/site-packages/pandas/io/parsers/readers.py in _read(filepath_or_buffer, kwds)
    480 
    481     # Create the parser.
--> 482     parser = TextFileReader(filepath_or_buffer, **kwds)
    483 
    484     if chunksize or iterator:

/opt/conda/lib/python3.9/site-packages/pandas/io/parsers/readers.py in __init__(self, f, engine, **kwds)
    809             self.options["has_index_names"] = kwds["has_index_names"]
    810 
--> 811         self._engine = self._make_engine(self.engine)
    812 
    813     def close(self):

/opt/conda/lib/python3.9/site-packages/pandas/io/parsers/readers.py in _make_engine(self, engine)
   1038             )
   1039         # error: Too many arguments for "ParserBase"
-> 1040         return mapping[engine](self.f, **self.options)  # type: ignore[call-arg]
   1041 
   1042     def _failover_to_python(self):

/opt/conda/lib/python3.9/site-packages/pandas/io/parsers/c_parser_wrapper.py in __init__(self, src, **kwds)
     49 
     50         # open handles
---> 51         self._open_handles(src, kwds)
     52         assert self.handles is not None
     53 

/opt/conda/lib/python3.9/site-packages/pandas/io/parsers/base_parser.py in _open_handles(self, src, kwds)
    220         Let the readers open IOHandles after they are done with their potential raises.
    221         """
--> 222         self.handles = get_handle(
    223             src,
    224             "r",

/opt/conda/lib/python3.9/site-packages/pandas/io/common.py in get_handle(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)
    607 
    608     # open URLs
--> 609     ioargs = _get_filepath_or_buffer(
    610         path_or_buf,
    611         encoding=encoding,

/opt/conda/lib/python3.9/site-packages/pandas/io/common.py in _get_filepath_or_buffer(filepath_or_buffer, encoding, compression, mode, storage_options)
    310         # assuming storage_options is to be interpreted as headers
    311         req_info = urllib.request.Request(filepath_or_buffer, headers=storage_options)
--> 312         with urlopen(req_info) as req:
    313             content_encoding = req.headers.get("Content-Encoding", None)
    314             if content_encoding == "gzip":

/opt/conda/lib/python3.9/site-packages/pandas/io/common.py in urlopen(*args, **kwargs)
    210     import urllib.request
    211 
--> 212     return urllib.request.urlopen(*args, **kwargs)
    213 
    214 

/opt/conda/lib/python3.9/urllib/request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    212     else:
    213         opener = _opener
--> 214     return opener.open(url, data, timeout)
    215 
    216 def install_opener(opener):

/opt/conda/lib/python3.9/urllib/request.py in open(self, fullurl, data, timeout)
    521         for processor in self.process_response.get(protocol, []):
    522             meth = getattr(processor, meth_name)
--> 523             response = meth(req, response)
    524 
    525         return response

/opt/conda/lib/python3.9/urllib/request.py in http_response(self, request, response)
    630         # request was successfully received, understood, and accepted.
    631         if not (200 <= code < 300):
--> 632             response = self.parent.error(
    633                 'http', request, response, code, msg, hdrs)
    634 

/opt/conda/lib/python3.9/urllib/request.py in error(self, proto, *args)
    559         if http_err:
    560             args = (dict, 'default', 'http_error_default') + orig_args
--> 561             return self._call_chain(*args)
    562 
    563 # XXX probably also want an abstract factory that knows when it makes

/opt/conda/lib/python3.9/urllib/request.py in _call_chain(self, chain, kind, meth_name, *args)
    492         for handler in handlers:
    493             func = getattr(handler, meth_name)
--> 494             result = func(*args)
    495             if result is not None:
    496                 return result

/opt/conda/lib/python3.9/urllib/request.py in http_error_default(self, req, fp, code, msg, hdrs)
    639 class HTTPDefaultErrorHandler(BaseHandler):
    640     def http_error_default(self, req, fp, code, msg, hdrs):
--> 641         raise HTTPError(req.full_url, code, msg, hdrs, fp)
    642 
    643 class HTTPRedirectHandler(BaseHandler):

HTTPError: HTTP Error 500: Internal Server Error
names.to_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa_names.pq")
names = pandas.read_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa_names.pq")
interpolated = interpolated.merge(names[["TTWA11CD", "TTWA11NM"]], on="TTWA11CD", how="left")
interpolated
Countryside agriculture Accessible suburbia Open sprawl Wild countryside Warehouse/Park land Gridded residential quarters Urban buffer Disconnected suburbia Dense residential neighbourhoods Connected residential neighbourhoods Dense urban neighbourhoods Local urbanity Concentrated urbanity Regional urbanity Metropolitan urbanity Hyper concentrated urbanity geometry TTWA11CD TTWA11NM
0 0.223470 0.043759 0.176207 0.078137 1.209109e-03 0.000215 0.464410 0.003625 0.006018 7.622296e-04 0.002179 0.000008 0.0 0.000000 0.000000 0.0 POLYGON ((443116.607 409861.824, 444593.769 40... E30000004 Barnsley
1 0.167767 0.044535 0.228543 0.031195 8.260556e-03 0.002243 0.431150 0.008945 0.032706 1.263258e-02 0.023457 0.008332 0.0 0.000230 0.000000 0.0 POLYGON ((404536.924 450487.224, 406675.831 44... E30000018 Bradford
2 0.506016 0.008178 0.078606 0.116988 7.743638e-03 0.000413 0.252566 0.004335 0.018123 1.105669e-03 0.005320 0.000605 0.0 0.000000 0.000000 0.0 POLYGON ((417371.807 423577.976, 417747.206 42... E30000029 Halifax
3 0.333247 0.000010 0.002516 0.626520 6.712196e-04 0.000000 0.036192 0.000069 0.000568 4.415132e-07 0.000182 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((399705.754 475251.492, 400486.847 47... E30000039 Skipton
4 0.803093 0.003389 0.021314 0.029620 4.454053e-03 0.000505 0.121557 0.000286 0.004360 4.049208e-04 0.000706 0.000240 0.0 0.000074 0.000021 0.0 POLYGON ((381318.618 95599.564, 382904.110 952... E30000046 Dorchester and Weymouth
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
213 0.294169 0.000185 0.000677 0.637449 1.737449e-05 0.000003 0.031029 0.000000 0.000199 1.370748e-05 0.000000 0.000000 0.0 0.000000 0.000000 0.0 MULTIPOLYGON (((212467.543 322328.962, 210862.... W22000030 Pwllheli and Porthmadog
214 0.335685 0.009770 0.006090 0.555019 3.346282e-04 0.001034 0.089543 0.000154 0.000000 2.896387e-04 0.000000 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((323624.950 374399.714, 321442.625 37... W22000031 Rhyl
215 0.285298 0.017182 0.035248 0.108456 1.686457e-02 0.007052 0.510910 0.001141 0.002975 1.466345e-03 0.001266 0.000990 0.0 0.000086 0.000000 0.0 POLYGON ((298705.805 215503.170, 298231.853 21... W22000032 Swansea
216 0.226700 0.000080 0.000736 0.749014 8.903418e-07 0.000000 0.016699 0.000098 0.000000 0.000000e+00 0.000000 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((300174.007 330847.935, 298615.652 32... W22000033 Tywyn and Dolgellau
217 0.677904 0.008354 0.019103 0.068111 3.937673e-03 0.000004 0.216287 0.002296 0.002831 4.259803e-04 0.000747 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((351207.619 343162.826, 350623.359 34... W22000034 Wrexham

218 rows × 19 columns

interpolated.columns = ['Countryside agriculture', 'Accessible suburbia', 'Open sprawl',
       'Wild countryside', 'Warehouse/Park land', 'Gridded residential quarters',
       'Urban buffer', 'Disconnected suburbia',
       'Dense residential neighbourhoods',
       'Connected residential neighbourhoods', 'Dense urban neighbourhoods',
       'Local urbanity', 'Concentrated urbanity', 'Regional urbanity',
       'Metropolitan urbanity', 'Hyper concentrated urbanity', 'geometry', 'TTWA11CD',
       'TTWA11NM']
interpolated = geopandas.GeoDataFrame(interpolated, crs=27700)
interpolated.to_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa_interpolated.pq")
/tmp/ipykernel_420582/3951706392.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.*')
  interpolated.to_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa_interpolated.pq")
interpolated.plot()
<AxesSubplot:>
../_images/ttwa_27_1.png
interpolated = geopandas.read_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa_interpolated.pq")
import matplotlib.pyplot as plt
import urbangrammar_graphics as ugg
plot_data = interpolated.set_index("TTWA11NM").T.drop(["geometry", "TTWA11CD"])
plot_data
TTWA11NM Barnsley Bradford Halifax Skipton Dorchester and Weymouth Falmouth Grantham Hastings Hexham Isle of Wight ... Cardiff Cardigan Colwyn Bay Llanelli Merthyr Tydfil Pwllheli and Porthmadog Rhyl Swansea Tywyn and Dolgellau Wrexham
Countryside agriculture 0.22347 0.167767 0.506016 0.333247 0.803093 0.818335 0.895052 0.767591 0.094503 0.599603 ... 0.195818 0.523145 0.248822 0.314656 0.355109 0.294169 0.335685 0.285298 0.2267 0.677904
Accessible suburbia 0.043759 0.044535 0.008178 0.00001 0.003389 0.001462 0.003266 0.029322 0.0 0.025276 ... 0.026761 0.0 0.008323 0.000882 0.001534 0.000185 0.00977 0.017182 0.00008 0.008354
Open sprawl 0.176207 0.228543 0.078606 0.002516 0.021314 0.014444 0.008395 0.015181 0.000812 0.019297 ... 0.104238 0.000554 0.006357 0.004573 0.04385 0.000677 0.00609 0.035248 0.000736 0.019103
Wild countryside 0.078137 0.031195 0.116988 0.62652 0.02962 0.025869 0.00005 0.000017 0.897572 0.000087 ... 0.0 0.457116 0.666861 0.614383 0.203098 0.637449 0.555019 0.108456 0.749014 0.068111
Warehouse/Park land 0.001209 0.008261 0.007744 0.000671 0.004454 0.000537 0.000426 0.000163 0.000008 0.000908 ... 0.033123 0.000037 0.002164 0.000003 0.009065 0.000017 0.000335 0.016865 0.000001 0.003938
Gridded residential quarters 0.000215 0.002243 0.000413 0.0 0.000505 0.003124 0.000075 0.0 0.0 0.006657 ... 0.018411 0.0 0.0008 0.001571 0.002301 0.000003 0.001034 0.007052 0.0 0.000004
Urban buffer 0.46441 0.43115 0.252566 0.036192 0.121557 0.094407 0.09079 0.165562 0.007011 0.32411 ... 0.579492 0.007042 0.059214 0.059388 0.382751 0.031029 0.089543 0.51091 0.016699 0.216287
Disconnected suburbia 0.003625 0.008945 0.004335 0.000069 0.000286 0.002359 0.000676 0.003296 0.00001 0.000196 ... 0.007812 0.000003 0.000006 0.000143 0.000539 0.0 0.000154 0.001141 0.000098 0.002296
Dense residential neighbourhoods 0.006018 0.032706 0.018123 0.000568 0.00436 0.000202 0.001139 0.004595 0.000085 0.003108 ... 0.008038 0.0 0.000323 0.000008 0.000775 0.000199 0.0 0.002975 0.0 0.002831
Connected residential neighbourhoods 0.000762 0.012633 0.001106 0.0 0.000405 0.001662 0.000002 0.003681 0.0 0.000155 ... 0.008753 0.0 0.002737 0.000003 0.000977 0.000014 0.00029 0.001466 0.0 0.000426
Dense urban neighbourhoods 0.002179 0.023457 0.00532 0.000182 0.000706 0.0 0.000129 0.001751 0.0 0.0 ... 0.011502 0.0 0.000005 0.0 0.0 0.0 0.0 0.001266 0.0 0.000747
Local urbanity 0.000008 0.008332 0.000605 0.0 0.00024 0.000177 0.0 0.000069 0.0 0.0 ... 0.003292 0.0 0.0 0.0 0.0 0.0 0.0 0.00099 0.0 0.0
Concentrated urbanity 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Regional urbanity 0.0 0.00023 0.0 0.0 0.000074 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000086 0.0 0.0
Metropolitan urbanity 0.0 0.0 0.0 0.0 0.000021 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Hyper concentrated urbanity 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

16 rows × 218 columns

cmap = ugg.get_colormap(20, randomize=False)
cols = cmap.colors

symbology = {'0_0': cols[16],
             '1_0': cols[15],
             '3_0': cols[9],
             '4_0': cols[12],
             '5_0': cols[21],
             '6_0': cols[8],
             '7_0': cols[4],
             '8_0': cols[18],
             '2_0': cols[6],
             '2_1': cols[23],
             '2_2': cols[19],
             '9_0': cols[7],
             '9_1': cols[3],
             '9_2': cols[22],
             '9_4': cols[11],
             '9_5': cols[14],
            }
symbology = {types[k]:v for k, v in symbology.items()}
plot_data.T["Wild countryside"].sort_values(ascending=False).iloc[:50].plot.bar(figsize=(18, 7))
<AxesSubplot:xlabel='TTWA11NM'>
../_images/ttwa_32_1.png
for sig in plot_data.index:
    
    ax = interpolated.plot(sig, figsize=(15, 15), legend=True)
    ax.axis('off')
    plt.savefig(f"../../urbangrammar_samba/spatial_signatures/esda/ttwa_maps/{sig}.png")
    plt.close()
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
/tmp/ipykernel_420582/2376116443.py in <module>
      3     ax = interpolated.plot(sig, figsize=(15, 15), legend=True)
      4     ax.axis('off')
----> 5     plt.savefig(f"../../urbangrammar_samba/spatial_signatures/esda/ttwa_maps/{sig}.png")
      6     plt.close()

/opt/conda/lib/python3.9/site-packages/matplotlib/pyplot.py in savefig(*args, **kwargs)
    964 def savefig(*args, **kwargs):
    965     fig = gcf()
--> 966     res = fig.savefig(*args, **kwargs)
    967     fig.canvas.draw_idle()   # need this if 'transparent=True' to reset colors
    968     return res

/opt/conda/lib/python3.9/site-packages/matplotlib/figure.py in savefig(self, fname, transparent, **kwargs)
   3013                 patch.set_edgecolor('none')
   3014 
-> 3015         self.canvas.print_figure(fname, **kwargs)
   3016 
   3017         if transparent:

/opt/conda/lib/python3.9/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2253                 # force the figure dpi to 72), so we need to set it again here.
   2254                 with cbook._setattr_cm(self.figure, dpi=dpi):
-> 2255                     result = print_method(
   2256                         filename,
   2257                         facecolor=facecolor,

/opt/conda/lib/python3.9/site-packages/matplotlib/backend_bases.py in wrapper(*args, **kwargs)
   1667             kwargs.pop(arg)
   1668 
-> 1669         return func(*args, **kwargs)
   1670 
   1671     return wrapper

/opt/conda/lib/python3.9/site-packages/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, metadata, pil_kwargs, *args)
    507         """
    508         FigureCanvasAgg.draw(self)
--> 509         mpl.image.imsave(
    510             filename_or_obj, self.buffer_rgba(), format="png", origin="upper",
    511             dpi=self.figure.dpi, metadata=metadata, pil_kwargs=pil_kwargs)

/opt/conda/lib/python3.9/site-packages/matplotlib/image.py in imsave(fname, arr, vmin, vmax, cmap, format, origin, dpi, metadata, pil_kwargs)
   1614         pil_kwargs.setdefault("format", format)
   1615         pil_kwargs.setdefault("dpi", (dpi, dpi))
-> 1616         image.save(fname, **pil_kwargs)
   1617 
   1618 

/opt/conda/lib/python3.9/site-packages/PIL/Image.py in save(self, fp, format, **params)
   2230                 fp = builtins.open(filename, "r+b")
   2231             else:
-> 2232                 fp = builtins.open(filename, "w+b")
   2233 
   2234         try:

FileNotFoundError: [Errno 2] No such file or directory: '../../urbangrammar_samba/spatial_signatures/esda/ttwa_maps/Warehouse/Park land.png'
../_images/ttwa_33_1.png
fig, axs = plt.subplots(4, 4, figsize=(20, 30))
axs = axs.flatten()
for i, sig in enumerate(plot_data.index):
    interpolated.plot(sig, ax=axs[i], legend=True)
    axs[i].axis("off")
    axs[i].set_title(sig)
../_images/ttwa_34_0.png
ax = plot_data.T.plot.bar(color=list(symbology.values()), stacked=True, figsize=(40, 10), legend=False)
../_images/ttwa_35_0.png
ax = plot_data["Barnsley"].plot.pie(colors=list(symbology.values()), labels=None, normalize=True)
ax.add_artist(plt.Circle((0,0), .7, color="w"))
<matplotlib.patches.Circle at 0x7f24417c2f70>
../_images/ttwa_36_1.png
plot_data
TTWA11NM Barnsley Bradford Halifax Skipton Dorchester and Weymouth Falmouth Grantham Hastings Hexham Isle of Wight ... Cardiff Cardigan Colwyn Bay Llanelli Merthyr Tydfil Pwllheli and Porthmadog Rhyl Swansea Tywyn and Dolgellau Wrexham
Countryside agriculture 0.22347 0.167767 0.506016 0.333247 0.803093 0.818335 0.895052 0.767591 0.094503 0.599603 ... 0.195818 0.523145 0.248822 0.314656 0.355109 0.294169 0.335685 0.285298 0.2267 0.677904
Accessible suburbia 0.043759 0.044535 0.008178 0.00001 0.003389 0.001462 0.003266 0.029322 0.0 0.025276 ... 0.026761 0.0 0.008323 0.000882 0.001534 0.000185 0.00977 0.017182 0.00008 0.008354
Open sprawl 0.176207 0.228543 0.078606 0.002516 0.021314 0.014444 0.008395 0.015181 0.000812 0.019297 ... 0.104238 0.000554 0.006357 0.004573 0.04385 0.000677 0.00609 0.035248 0.000736 0.019103
Wild countryside 0.078137 0.031195 0.116988 0.62652 0.02962 0.025869 0.00005 0.000017 0.897572 0.000087 ... 0.0 0.457116 0.666861 0.614383 0.203098 0.637449 0.555019 0.108456 0.749014 0.068111
Warehouse/Park land 0.001209 0.008261 0.007744 0.000671 0.004454 0.000537 0.000426 0.000163 0.000008 0.000908 ... 0.033123 0.000037 0.002164 0.000003 0.009065 0.000017 0.000335 0.016865 0.000001 0.003938
Gridded residential quarters 0.000215 0.002243 0.000413 0.0 0.000505 0.003124 0.000075 0.0 0.0 0.006657 ... 0.018411 0.0 0.0008 0.001571 0.002301 0.000003 0.001034 0.007052 0.0 0.000004
Urban buffer 0.46441 0.43115 0.252566 0.036192 0.121557 0.094407 0.09079 0.165562 0.007011 0.32411 ... 0.579492 0.007042 0.059214 0.059388 0.382751 0.031029 0.089543 0.51091 0.016699 0.216287
Disconnected suburbia 0.003625 0.008945 0.004335 0.000069 0.000286 0.002359 0.000676 0.003296 0.00001 0.000196 ... 0.007812 0.000003 0.000006 0.000143 0.000539 0.0 0.000154 0.001141 0.000098 0.002296
Dense residential neighbourhoods 0.006018 0.032706 0.018123 0.000568 0.00436 0.000202 0.001139 0.004595 0.000085 0.003108 ... 0.008038 0.0 0.000323 0.000008 0.000775 0.000199 0.0 0.002975 0.0 0.002831
Connected residential neighbourhoods 0.000762 0.012633 0.001106 0.0 0.000405 0.001662 0.000002 0.003681 0.0 0.000155 ... 0.008753 0.0 0.002737 0.000003 0.000977 0.000014 0.00029 0.001466 0.0 0.000426
Dense urban neighbourhoods 0.002179 0.023457 0.00532 0.000182 0.000706 0.0 0.000129 0.001751 0.0 0.0 ... 0.011502 0.0 0.000005 0.0 0.0 0.0 0.0 0.001266 0.0 0.000747
Local urbanity 0.000008 0.008332 0.000605 0.0 0.00024 0.000177 0.0 0.000069 0.0 0.0 ... 0.003292 0.0 0.0 0.0 0.0 0.0 0.0 0.00099 0.0 0.0
Concentrated urbanity 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Regional urbanity 0.0 0.00023 0.0 0.0 0.000074 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000086 0.0 0.0
Metropolitan urbanity 0.0 0.0 0.0 0.0 0.000021 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Hyper concentrated urbanity 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

16 rows × 218 columns

fig, axs = plt.subplots(15, 15, figsize=(40, 40))
axs = axs.flatten()
for i, place in enumerate(plot_data.columns):
    plot_data[place].plot.pie(colors=list(symbology.values()), labels=None, ax=axs[i], normalize=True)
    axs[i].axis("off")
    axs[i].add_artist(plt.Circle((0,0), .7, color="w"))
    axs[i].set_title(place)
../_images/ttwa_38_0.png
interpolated = geopandas.read_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa_interpolated.pq")
interpolated = interpolated.set_index("TTWA11NM")
plot_data = geopandas.GeoDataFrame(columns=["level", "order", "area", "urbanity", "geometry"], crs=interpolated.crs)
mapdata = interpolated.set_geometry(interpolated.centroid)

centres = ['Hyper concentrated urbanity', 'Concentrated urbanity', 'Metropolitan urbanity', 'Regional urbanity', 'Local urbanity', 'Dense urban neighbourhoods']
sizes = pandas.DataFrame()
for centre in centres:
    sizes[centre] = interpolated[centre] * interpolated.area
centroids = interpolated.centroid
for level, c in enumerate(centres):
    sub = interpolated[interpolated[c] > 0]
    area = sub.area
    sub["sorter"] = sub[c] * area
    sub = sub.sort_values("sorter", ascending=False)
    for i, ix in enumerate(sub.index):
        plot_data.loc[ix] = [level, i, sub["sorter"].loc[ix], c, centroids.loc[ix]]
    interpolated = interpolated.drop(sub.index)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
plot_data
level order area urbanity geometry
London 0 0 1.306116e+06 Hyper concentrated urbanity POINT (538745.517 181341.137)
Birmingham 2 0 1.075148e+06 Metropolitan urbanity POINT (411388.314 285146.915)
Edinburgh 2 1 6.384964e+05 Metropolitan urbanity POINT (336390.208 665534.358)
Glasgow 2 2 6.059172e+05 Metropolitan urbanity POINT (254347.160 665607.051)
Manchester 2 3 5.153730e+05 Metropolitan urbanity POINT (386789.011 394849.149)
... ... ... ... ... ...
Clacton 5 44 1.356900e+03 Dense urban neighbourhoods POINT (616875.217 223103.518)
Yeovil 5 45 1.311523e+03 Dense urban neighbourhoods POINT (353450.605 119753.694)
Kendal 5 46 8.299633e+02 Dense urban neighbourhoods POINT (352724.630 492020.453)
Worksop and Retford 5 47 6.096959e+02 Dense urban neighbourhoods POINT (468352.260 381552.153)
Bridport 5 48 1.525966e+02 Dense urban neighbourhoods POINT (344728.416 97774.130)

152 rows × 5 columns

sizes = sizes.cumsum(axis=1)
sizes
Hyper concentrated urbanity Concentrated urbanity Metropolitan urbanity Regional urbanity Local urbanity Dense urban neighbourhoods
TTWA11NM
Barnsley 0.0 0.0 0.000000 0.000000 2.652940e+03 7.457278e+05
Bradford 0.0 0.0 0.000000 79723.179688 2.965356e+06 1.108895e+07
Halifax 0.0 0.0 0.000000 0.000000 2.213591e+05 2.167267e+06
Skipton 0.0 0.0 0.000000 0.000000 0.000000e+00 2.157967e+05
Dorchester and Weymouth 0.0 0.0 15383.532227 68559.571289 2.408603e+05 7.469582e+05
... ... ... ... ... ... ...
Pwllheli and Porthmadog 0.0 0.0 0.000000 0.000000 0.000000e+00 0.000000e+00
Rhyl 0.0 0.0 0.000000 0.000000 0.000000e+00 0.000000e+00
Swansea 0.0 0.0 0.000000 86499.750000 1.083695e+06 2.358544e+06
Tywyn and Dolgellau 0.0 0.0 0.000000 0.000000 0.000000e+00 0.000000e+00
Wrexham 0.0 0.0 0.000000 0.000000 0.000000e+00 3.795116e+05

218 rows × 6 columns

fig, ax = plt.subplots(figsize=(16, 16))
scaler = 20000

for i, centre in enumerate(centres[::-1]):
    if centre == 'Dense urban neighbourhoods':
        mapdata.drop("London").plot(markersize=sizes[centre].drop("London") / scaler, ax=ax, zorder=i+10, color=symbology[centre], edgecolor="w")
        mapdata.loc[["London"]].plot(markersize=sizes[centre].loc[["London"]] / scaler, ax=ax, zorder=i, color=symbology[centre], edgecolor="w")
    else:
        mapdata.drop("London").plot(markersize=sizes[centre].drop("London") / scaler, ax=ax, zorder=i+10, color=symbology[centre])
        mapdata.loc[["London"]].plot(markersize=sizes[centre].loc[["London"]] / scaler, ax=ax, zorder=i, color=symbology[centre])

ax.set_axis_off()
plt.savefig("figs/hierarchy_map.pdf")
../_images/ttwa_47_0.png
fig, axs = plt.subplots(1, 6, figsize=(52, 25))
scaler = 20000
axs = axs.flatten()

for i, centre in enumerate(centres[::-1]):
    mapdata.drop("London").plot(markersize=sizes[centre].drop("London") / scaler, ax=axs[i], zorder=i+10, color=symbology[centre], edgecolor="w")
    mapdata.loc[["London"]].plot(markersize=sizes[centre].loc[["London"]] / scaler, ax=axs[i], zorder=i, color=symbology[centre], edgecolor="w")

    axs[i].set_axis_off()
plt.savefig("figs/hierarchy_map_layers.pdf")
../_images/ttwa_48_0.png
plot_data
level order area urbanity geometry
London 0 0 1.306116e+06 Hyper concentrated urbanity POINT (538745.517 181341.137)
Birmingham 2 0 1.075148e+06 Metropolitan urbanity POINT (411388.314 285146.915)
Edinburgh 2 1 6.384964e+05 Metropolitan urbanity POINT (336390.208 665534.358)
Glasgow 2 2 6.059172e+05 Metropolitan urbanity POINT (254347.160 665607.051)
Manchester 2 3 5.153730e+05 Metropolitan urbanity POINT (386789.011 394849.149)
... ... ... ... ... ...
Clacton 5 44 1.356900e+03 Dense urban neighbourhoods POINT (616875.217 223103.518)
Yeovil 5 45 1.311523e+03 Dense urban neighbourhoods POINT (353450.605 119753.694)
Kendal 5 46 8.299633e+02 Dense urban neighbourhoods POINT (352724.630 492020.453)
Worksop and Retford 5 47 6.096959e+02 Dense urban neighbourhoods POINT (468352.260 381552.153)
Bridport 5 48 1.525966e+02 Dense urban neighbourhoods POINT (344728.416 97774.130)

152 rows × 5 columns

mapdata[["level", "order"]] = plot_data[["level", "order"]]
mapdata.order.max()
67
mapdata.loc[mapdata.level == 1, "order"] = mapdata.loc[mapdata.level == 1, "order"] * 5
mapdata.loc[mapdata.level == 2, "order"] = mapdata.loc[mapdata.level == 2, "order"] * 2.5
mapdata.loc[mapdata.level == 4, "order"] = mapdata.loc[mapdata.level == 4, "order"] * 1.5
for l in mapdata.level.dropna().unique():
    mapdata.loc[mapdata.level == l, "x"] = (mapdata.loc[mapdata.level == l, "order"] - mapdata.loc[mapdata.level == l, "order"].mean()) / mapdata.loc[mapdata.level == l, "order"].std()
mapdata.loc["London", 'x'] = 0 
fig, ax = plt.subplots(figsize=(10, 10))
scaler = 30000

for i, centre in enumerate(centres[::-1]):
    ax.scatter(mapdata.x * 10, 1 - mapdata.level * 10, s=sizes[centre] / scaler, zorder=i+10, color=symbology[centre])

ax.set_axis_off()
# ax.axis('equal')
ax.set_ylim(-50, 7)
plt.savefig("figs/hierarchy_diagram.pdf")
../_images/ttwa_56_0.png
fig, ax = plt.subplots(figsize=(10, 10))
scaler = 30000

for i, centre in enumerate(centres[::-1]):
    ax.scatter(mapdata.loc[["London"]].x * 10, 1 - mapdata.loc[["London"]].level * 10, s=sizes.loc[["London"]][centre] / scaler, zorder=i+10, color=symbology[centre])

ax.set_axis_off()
# ax.axis('equal')
# ax.set_ylim(-42, 7)
plt.savefig("figs/hierarchy_london.pdf")
../_images/ttwa_57_0.png
interpolated = geopandas.read_parquet("../../urbangrammar_samba/spatial_signatures/esda/ttwa_interpolated.pq")
interpolated = interpolated.set_index("TTWA11NM")
interpolated
Countryside agriculture Accessible suburbia Open sprawl Wild countryside Warehouse/Park land Gridded residential quarters Urban buffer Disconnected suburbia Dense residential neighbourhoods Connected residential neighbourhoods Dense urban neighbourhoods Local urbanity Concentrated urbanity Regional urbanity Metropolitan urbanity Hyper concentrated urbanity geometry TTWA11CD
TTWA11NM
Barnsley 0.223470 0.043759 0.176207 0.078137 1.209109e-03 0.000215 0.464410 0.003625 0.006018 7.622296e-04 0.002179 0.000008 0.0 0.000000 0.000000 0.0 POLYGON ((443116.607 409861.824, 444593.769 40... E30000004
Bradford 0.167767 0.044535 0.228543 0.031195 8.260556e-03 0.002243 0.431150 0.008945 0.032706 1.263258e-02 0.023457 0.008332 0.0 0.000230 0.000000 0.0 POLYGON ((404536.924 450487.224, 406675.831 44... E30000018
Halifax 0.506016 0.008178 0.078606 0.116988 7.743638e-03 0.000413 0.252566 0.004335 0.018123 1.105669e-03 0.005320 0.000605 0.0 0.000000 0.000000 0.0 POLYGON ((417371.807 423577.976, 417747.206 42... E30000029
Skipton 0.333247 0.000010 0.002516 0.626520 6.712196e-04 0.000000 0.036192 0.000069 0.000568 4.415132e-07 0.000182 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((399705.754 475251.492, 400486.847 47... E30000039
Dorchester and Weymouth 0.803093 0.003389 0.021314 0.029620 4.454053e-03 0.000505 0.121557 0.000286 0.004360 4.049208e-04 0.000706 0.000240 0.0 0.000074 0.000021 0.0 POLYGON ((381318.618 95599.564, 382904.110 952... E30000046
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
Pwllheli and Porthmadog 0.294169 0.000185 0.000677 0.637449 1.737449e-05 0.000003 0.031029 0.000000 0.000199 1.370748e-05 0.000000 0.000000 0.0 0.000000 0.000000 0.0 MULTIPOLYGON (((212467.543 322328.962, 210862.... W22000030
Rhyl 0.335685 0.009770 0.006090 0.555019 3.346282e-04 0.001034 0.089543 0.000154 0.000000 2.896387e-04 0.000000 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((323624.950 374399.714, 321442.625 37... W22000031
Swansea 0.285298 0.017182 0.035248 0.108456 1.686457e-02 0.007052 0.510910 0.001141 0.002975 1.466345e-03 0.001266 0.000990 0.0 0.000086 0.000000 0.0 POLYGON ((298705.805 215503.170, 298231.853 21... W22000032
Tywyn and Dolgellau 0.226700 0.000080 0.000736 0.749014 8.903418e-07 0.000000 0.016699 0.000098 0.000000 0.000000e+00 0.000000 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((300174.007 330847.935, 298615.652 32... W22000033
Wrexham 0.677904 0.008354 0.019103 0.068111 3.937673e-03 0.000004 0.216287 0.002296 0.002831 4.259803e-04 0.000747 0.000000 0.0 0.000000 0.000000 0.0 POLYGON ((351207.619 343162.826, 350623.359 34... W22000034

218 rows × 18 columns

for_heatmap = interpolated.drop(columns=["geometry", "TTWA11CD"])
for_heatmap.T
TTWA11NM Barnsley Bradford Halifax Skipton Dorchester and Weymouth Falmouth Grantham Hastings Hexham Isle of Wight ... Cardiff Cardigan Colwyn Bay Llanelli Merthyr Tydfil Pwllheli and Porthmadog Rhyl Swansea Tywyn and Dolgellau Wrexham
Countryside agriculture 0.223470 0.167767 0.506016 3.332466e-01 0.803093 0.818335 0.895052 0.767591 0.094503 0.599603 ... 0.195818 0.523145 0.248822 0.314656 0.355109 0.294169 0.335685 0.285298 2.267002e-01 0.677904
Accessible suburbia 0.043759 0.044535 0.008178 9.679447e-06 0.003389 0.001462 0.003266 0.029322 0.000000 0.025276 ... 0.026761 0.000000 0.008323 0.000882 0.001534 0.000185 0.009770 0.017182 7.951733e-05 0.008354
Open sprawl 0.176207 0.228543 0.078606 2.516165e-03 0.021314 0.014444 0.008395 0.015181 0.000812 0.019297 ... 0.104238 0.000554 0.006357 0.004573 0.043850 0.000677 0.006090 0.035248 7.362045e-04 0.019103
Wild countryside 0.078137 0.031195 0.116988 6.265198e-01 0.029620 0.025869 0.000050 0.000017 0.897572 0.000087 ... 0.000000 0.457116 0.666861 0.614383 0.203098 0.637449 0.555019 0.108456 7.490144e-01 0.068111
Warehouse/Park land 0.001209 0.008261 0.007744 6.712196e-04 0.004454 0.000537 0.000426 0.000163 0.000008 0.000908 ... 0.033123 0.000037 0.002164 0.000003 0.009065 0.000017 0.000335 0.016865 8.903418e-07 0.003938
Gridded residential quarters 0.000215 0.002243 0.000413 0.000000e+00 0.000505 0.003124 0.000075 0.000000 0.000000 0.006657 ... 0.018411 0.000000 0.000800 0.001571 0.002301 0.000003 0.001034 0.007052 0.000000e+00 0.000004
Urban buffer 0.464410 0.431150 0.252566 3.619192e-02 0.121557 0.094407 0.090790 0.165562 0.007011 0.324110 ... 0.579492 0.007042 0.059214 0.059388 0.382751 0.031029 0.089543 0.510910 1.669930e-02 0.216287
Disconnected suburbia 0.003625 0.008945 0.004335 6.877031e-05 0.000286 0.002359 0.000676 0.003296 0.000010 0.000196 ... 0.007812 0.000003 0.000006 0.000143 0.000539 0.000000 0.000154 0.001141 9.760898e-05 0.002296
Dense residential neighbourhoods 0.006018 0.032706 0.018123 5.675908e-04 0.004360 0.000202 0.001139 0.004595 0.000085 0.003108 ... 0.008038 0.000000 0.000323 0.000008 0.000775 0.000199 0.000000 0.002975 0.000000e+00 0.002831
Connected residential neighbourhoods 0.000762 0.012633 0.001106 4.415132e-07 0.000405 0.001662 0.000002 0.003681 0.000000 0.000155 ... 0.008753 0.000000 0.002737 0.000003 0.000977 0.000014 0.000290 0.001466 0.000000e+00 0.000426
Dense urban neighbourhoods 0.002179 0.023457 0.005320 1.824795e-04 0.000706 0.000000 0.000129 0.001751 0.000000 0.000000 ... 0.011502 0.000000 0.000005 0.000000 0.000000 0.000000 0.000000 0.001266 0.000000e+00 0.000747
Local urbanity 0.000008 0.008332 0.000605 0.000000e+00 0.000240 0.000177 0.000000 0.000069 0.000000 0.000000 ... 0.003292 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000990 0.000000e+00 0.000000
Concentrated urbanity 0.000000 0.000000 0.000000 0.000000e+00 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000e+00 0.000000
Regional urbanity 0.000000 0.000230 0.000000 0.000000e+00 0.000074 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000086 0.000000e+00 0.000000
Metropolitan urbanity 0.000000 0.000000 0.000000 0.000000e+00 0.000021 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000e+00 0.000000
Hyper concentrated urbanity 0.000000 0.000000 0.000000 0.000000e+00 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000e+00 0.000000

16 rows × 218 columns

import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np
order = ['Wild countryside', 'Countryside agriculture', 'Urban buffer',
       'Warehouse/Park land', 'Open sprawl', 'Disconnected suburbia',
       'Accessible suburbia', 'Connected residential neighbourhoods',
       'Dense residential neighbourhoods', 'Gridded residential quarters',
       'Dense urban neighbourhoods', 'Local urbanity', 'Regional urbanity',
       'Metropolitan urbanity', 'Concentrated urbanity',
       'Hyper concentrated urbanity'
    ]
order.reverse()
for_heatmap = for_heatmap[
    order
]
plot_data2 = geopandas.GeoDataFrame(columns=["level", "order", "area", "urbanity", "geometry"], crs=interpolated.crs)
sizes = pandas.DataFrame()
for centre in order:
    sizes[centre] = interpolated[centre] * interpolated.area
centroids = interpolated.centroid
for level, c in enumerate(order):
    sub = interpolated[interpolated[c] > 0]
    area = sub.area
    sub["sorter"] = sub[c] * area
    sub = sub.sort_values("sorter", ascending=False)
    for i, ix in enumerate(sub.index):
        plot_data2.loc[ix] = [level, i, sub["sorter"].loc[ix], c, centroids.loc[ix]]
    interpolated = interpolated.drop(sub.index)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
/opt/conda/lib/python3.9/site-packages/geopandas/geodataframe.py:1351: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  super().__setitem__(key, value)
plot_data2
level order area urbanity geometry
London 0 0 1.306116e+06 Hyper concentrated urbanity POINT (538745.517 181341.137)
Birmingham 2 0 1.075148e+06 Metropolitan urbanity POINT (411388.314 285146.915)
Edinburgh 2 1 6.384964e+05 Metropolitan urbanity POINT (336390.208 665534.358)
Glasgow 2 2 6.059172e+05 Metropolitan urbanity POINT (254347.160 665607.051)
Manchester 2 3 5.153730e+05 Metropolitan urbanity POINT (386789.011 394849.149)
... ... ... ... ... ...
Portree 11 1 4.187323e+05 Open sprawl POINT (139392.915 845200.808)
Newton Stewart 11 2 3.890446e+05 Open sprawl POINT (243111.771 562519.436)
Mull and Islay 13 0 3.332326e+06 Urban buffer POINT (143779.227 704221.821)
Lochgilphead 13 1 6.808734e+05 Urban buffer POINT (188024.719 687097.024)
Broadford and Kyle of Lochalsh 13 2 2.705685e+05 Urban buffer POINT (187338.604 832547.182)

218 rows × 5 columns

Per proportion within TTWA

plt.subplots(figsize=(32, 8))
sns.heatmap(data=for_heatmap.loc[plot_data2.index].T, norm=LogNorm())
<AxesSubplot:>
../_images/ttwa_70_1.png

Per proportion of type within ttwa

plt.subplots(figsize=(32, 8))
sns.heatmap(data=(for_heatmap / for_heatmap.sum(axis=0)).loc[plot_data2.index].T, norm=LogNorm())
<AxesSubplot:>
../_images/ttwa_72_1.png
plt.subplots(figsize=(32, 8))
sns.heatmap(data=(for_heatmap / for_heatmap.sum(axis=0)).loc[plot_data2.index].T, norm=LogNorm(), cmap="magma_r")
<AxesSubplot:>
../_images/ttwa_73_1.png