New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plot chloropleth with consistent legend
and bins
#1019
Comments
Under the hood, geopandas uses mapclassify, and the easiest way to achieve what you want would be to just use it directly: import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
from mapclassify import Quantiles, User_Defined
# Note you can read directly from the URL
gdf = gpd.read_file('https://opendata.arcgis.com/datasets/8edafbe3276d4b56aec60991cbddda50_1.zip?outSR=%7B%22latestWkid%22%3A27700%2C%22wkid%22%3A27700%7D&session=850489311.1553456889'
)
# 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)))
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)
fig,(ax1,ax2,ax3,) = plt.subplots(1,3,figsize=(15,6))
# define your bins
bins = Quantiles(pop_gdf['central_pop'], 5).bins
# create a new column with the discretized values and plot that col
# repeat for each view
pop_gdf.assign(cl=User_Defined(df['low_pop'].dropna(), bins).yb).plot(
column='cl', ax=ax1, cmap='OrRd'
)
pop_gdf.assign(cl=User_Defined(df['central_pop'].dropna(), bins).yb).plot(
column='cl', ax=ax2, cmap='OrRd',
)
pop_gdf.assign(cl=User_Defined(df['high_pop'].dropna(), list(bins)).yb).plot(
column='cl', ax=ax3, cmap='OrRd',
)
for ax in (ax1,ax2,ax3,):
ax.axis('off') |
That's so great thank you. If you would forgive me - I have 2 questions about your plots.
(btw I have just looked at your research profile. That is some amazing work that you have done!) |
ah, sorry about that. I included i.e.
and if you play around with changing the legend location in the and thanks for the kind words about my work! :) |
fig,(ax1,ax2,ax3,) = plt.subplots(1,3,figsize=(15,6))
bins = Quantiles(pop_gdf['central_pop'], 5).bins
pop_gdf.assign(cl=User_Defined(pop_gdf['low_pop'].dropna(), bins).yb).plot(
column='cl', ax=ax1, cmap='OrRd'
)
pop_gdf.plot('central_pop', scheme='quantiles', ax=ax2, cmap='OrRd', legend=True, cax=ax3,
legend_kwds=dict(loc='upper right', bbox_to_anchor=(3.5, 0.75), title="Legend\n", frameon=False)
)
pop_gdf.assign(cl=User_Defined(pop_gdf['high_pop'].dropna(), list(bins)).yb).plot(
column='cl', ax=ax3, cmap='OrRd', legend=False
)
for ax in (ax1,ax2,ax3,):
ax.axis('off') |
Thank you, @tommylees112 for your question and you, @knaaptime for the precise answer. Issue resolved, closing. |
Is there a way to force the legend in a map with a binned scheme to be in a colorbar style instead of circles with labels? And label only the min and max ends? I'm sure there's a way with matplolib, but if you have an example handy it would be a huge help. |
@robroc did you found a solution to your question? would be interested to save some time here too! many thanks! |
@raphmu86 im not sure if this answers your question. If the column is numerical, it will show up as a colorbar.
|
@ShouravBR Does this work if you pass something into |
@robroc No, the colorbar does not show. Uneven ticks from the
|
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.The python code that reads the shapefile and creates a dummy
GeoDataFrame
for reproducing the behaviour.Join the shapefile from ONS and create a
geopandas.GeoDataFrame
Make the plots
I want all three
ax
objects to share the same bins (preferable thecentral_pop
scenarioquantiles
) so that the legend is consistent for the whole figure.This way I should see darker colors (more red) in the far right
ax
showing thehigh_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()
functionb) extract the colorscheme / bins from one
ax
and apply it to another.The text was updated successfully, but these errors were encountered: