OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

matplotlib geopandas plot chloropleth with set bins for colorscheme

  • Thread starter Thread starter Tommy Lees
  • Start date Start date
T

Tommy Lees

Guest

How do I set a consistent colorscheme for three axes in the same figure?​


The following should be a wholly reproducible example to run the code and get the same figure I have posted below.

Get the shapefile data from the Office for National Statistics. Run this in a terminal as a bash file / commands.

Code:
wget --output-document 'LA_authorities_boundaries.zip' 'https://opendata.arcgis.com/datasets/8edafbe3276d4b56aec60991cbddda50_1.zip?outSR=%7B%22latestWkid%22%3A27700%2C%22wkid%22%3A27700%7D&session=850489311.1553456889'

mkdir LA_authorities_boundaries
cd LA_authorities_boundaries
unzip ../LA_authorities_boundaries.zip

The python code that reads the shapefile and creates a dummy GeoDataFrame for reproducing the behaviour.

Code:
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt

gdf = gpd.read_file(
    'LA_authorities_boundaries/Local_Authority_Districts_December_2015_Full_Extent_Boundaries_in_Great_Britain.shp'
)

# 380 values
df = pd.DataFrame([])
df['AREA_CODE'] = gdf.lad15cd.values
df['central_pop'] = np.random.normal(30, 15, size=(len(gdf.lad15cd.values)))
df['low_pop'] = np.random.normal(10, 15, size=(len(gdf.lad15cd.values)))
df['high_pop'] = np.random.normal(50, 15, size=(len(gdf.lad15cd.values)))

Join the shapefile from ONS and create a geopandas.GeoDataFrame

Code:
def join_df_to_shp(pd_df, gpd_gdf):
    """"""
    df_ = pd.merge(pd_df, gpd_gdf[['lad15cd','geometry']], left_on='AREA_CODE', right_on='lad15cd', how='left')

    # DROP the NI counties
    df_ = df_.dropna(subset=['geometry'])

    # convert back to a geopandas object (for ease of plotting etc.)
    crs = {'init': 'epsg:4326'}
    gdf_ = gpd.GeoDataFrame(df_, crs=crs, geometry='geometry')
    # remove the extra area_code column joined from gdf
    gdf_.drop('lad15cd',axis=1, inplace=True)

    return gdf_

pop_gdf = join_df_to_shp(df, gdf)

Make the plots

Code:
fig,(ax1,ax2,ax3,) = plt.subplots(1,3,figsize=(15,6))

pop_gdf.plot(
    column='low_pop', ax=ax1, legend=True,  scheme='quantiles', cmap='OrRd',
)
pop_gdf.plot(
    column='central_pop', ax=ax2, legend=True, scheme='quantiles', cmap='OrRd',
)
pop_gdf.plot(
    column='high_pop', ax=ax3, legend=True,  scheme='quantiles', cmap='OrRd',
)
for ax in (ax1,ax2,ax3,):
    ax.axis('off')

enter image description here

I want all three ax objects to share the same bins (preferable the central_pop scenario quantiles) so that the legend is consistent for the whole figure. The quantiles from ONE scenario (central) would become the levels for all​


This way I should see darker colors (more red) in the far right ax showing the high_pop scenario.

How can I set the colorscheme bins for the whole figure / each of the ax objects?

The simplest way I can see this working is either a) Provide a set of bins to the geopandas.plot() function b) extract the colorscheme / bins from one ax and apply it to another.
<h1>How do I set a consistent colorscheme for three <code>axes</code> in the same figure?</h1>

<p>The following should be a wholly reproducible example to run the code and get the same figure I have posted below.</p>

<p>Get the shapefile data from the <a href="http://geoportal.statistics.gov.uk/...6aec60991cbddda50_1?selectedAttribute=lad15cd" rel="noreferrer">Office for National Statistics</a>. Run this in a terminal as a <code>bash</code> file / commands.</p>

<pre class="lang-sh prettyprint-override"><code>wget --output-document 'LA_authorities_boundaries.zip' 'https://opendata.arcgis.com/dataset...00,"wkid":27700}&session=850489311.1553456889'

mkdir LA_authorities_boundaries
cd LA_authorities_boundaries
unzip ../LA_authorities_boundaries.zip
</code></pre>

<p>The python code that reads the shapefile and creates a dummy <code>GeoDataFrame</code> for reproducing the behaviour.</p>

<pre class="lang-py prettyprint-override"><code>import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt

gdf = gpd.read_file(
'LA_authorities_boundaries/Local_Authority_Districts_December_2015_Full_Extent_Boundaries_in_Great_Britain.shp'
)

# 380 values
df = pd.DataFrame([])
df['AREA_CODE'] = gdf.lad15cd.values
df['central_pop'] = np.random.normal(30, 15, size=(len(gdf.lad15cd.values)))
df['low_pop'] = np.random.normal(10, 15, size=(len(gdf.lad15cd.values)))
df['high_pop'] = np.random.normal(50, 15, size=(len(gdf.lad15cd.values)))

</code></pre>

<p>Join the shapefile from ONS and create a <code>geopandas.GeoDataFrame</code></p>

<pre class="lang-py prettyprint-override"><code>def join_df_to_shp(pd_df, gpd_gdf):
""""""
df_ = pd.merge(pd_df, gpd_gdf[['lad15cd','geometry']], left_on='AREA_CODE', right_on='lad15cd', how='left')

# DROP the NI counties
df_ = df_.dropna(subset=['geometry'])

# convert back to a geopandas object (for ease of plotting etc.)
crs = {'init': 'epsg:4326'}
gdf_ = gpd.GeoDataFrame(df_, crs=crs, geometry='geometry')
# remove the extra area_code column joined from gdf
gdf_.drop('lad15cd',axis=1, inplace=True)

return gdf_

pop_gdf = join_df_to_shp(df, gdf)
</code></pre>

<p>Make the plots</p>

<pre class="lang-py prettyprint-override"><code>fig,(ax1,ax2,ax3,) = plt.subplots(1,3,figsize=(15,6))

pop_gdf.plot(
column='low_pop', ax=ax1, legend=True, scheme='quantiles', cmap='OrRd',
)
pop_gdf.plot(
column='central_pop', ax=ax2, legend=True, scheme='quantiles', cmap='OrRd',
)
pop_gdf.plot(
column='high_pop', ax=ax3, legend=True, scheme='quantiles', cmap='OrRd',
)
for ax in (ax1,ax2,ax3,):
ax.axis('off')
</code></pre>

<p><a href="https://i.sstatic.net/aNinv.png" rel="noreferrer"><img src="https://i.sstatic.net/aNinv.png" alt="enter image description here"></a></p>

<h1>I want all three <code>ax</code> objects to share the same bins (preferable the <code>central_pop</code> scenario <code>quantiles</code>) so that the legend is consistent for the whole figure. The <code>quantiles</code> from ONE scenario (central) would become the <code>levels</code> for all</h1>

<p>This way I should see darker colors (more red) in the far right <code>ax</code> showing the <code>high_pop</code> scenario.</p>

<p>How can I set the colorscheme bins for the whole figure / each of the <code>ax</code> objects?</p>

<p>The simplest way I can see this working is either
a) Provide a set of bins to the <code>geopandas.plot()</code> function
b) extract the colorscheme / bins from one <code>ax</code> and apply it to another.</p>
 

Latest posts

Top