3

There are multiple thing I want to edit with the colorbar in a geopandas world choropleth I'm creating. Namely the size (so that it roughly matches the map itself), the text size (which currently shows up far too small) and I also wanted to add a label to it. It seems from reading about a bit there's no easy way of doing that explicitly within geopandas and so i was wondering if anyone might have any workarounds at all to offer? Any help would be greatly appreciated.

This is the piece of code I'm currently using (for some context the mid section is simply merging lists with figures by country, which I'm using as the basis of the colouring, to the frame)

fig, ax = plt.subplots(figsize=(40,29.171))
world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))

world=pd.DataFrame(world)
world['LEADS']=0.1
world = world.set_index('name')
world['name']=world.index
for x, y in zip(Countries, country_counts):
    world.loc[x, 'LEADS'] = y
world=geopandas.GeoDataFrame(world)

world = world[(world.index != "Antarctica")]
ax.set_axis_off()
#ax.legend(title="Leads")
world.plot(ax=ax, column='LEADS', cmap='Oranges', legend=True,linewidth = 1.5)
plt.tight_layout()

plt.savefig('plot_image.png', bbox_inches='tight', transparent=True)

An ideal solution here would maintain the colours that the legend option has, specify size and text size and enable a label at the top of the bar. I'm struglling to work out how any of this is done myself unfortunatley.

EFZ
  • 127
  • 3
  • 10

2 Answers2

5

The answer found here helped me find a workaround.

import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize = (30,25))
vmin = data.column.min()
vmax = data.column.max()
data.plot(ax=ax,column = column,edgecolor='black',cmap = 'YlOrRd',legend = False)
plt.xlim([6,19])
plt.ylim([36,47.7])
plt.xticks([], [])
plt.yticks([], [])

cax = fig.add_axes([1, 0.1, 0.03, 0.8])
sm = plt.cm.ScalarMappable(cmap='YlOrRd', norm=plt.Normalize(vmin=vmin, vmax=vmax))
sm._A = []
cbr = fig.colorbar(sm, cax=cax,)
cbr.ax.tick_params(labelsize=200) 
plt.tight_layout()
plt.savefig(os.path.join('out','fig.png'),format = 'png',bbox_inches='tight')
plt.show()

Once you have your Colorbar object my_cbar, you can set properties in a matplotlib fashion. Here I changed the label size. Remember to use bbox_inches='tight' if you need to save the figure: otherwise the colorbar is not saved. My output is something like this, with modified colorbar fontsize. map with colorbar

ale-6
  • 345
  • 4
  • 13
  • "cbr.ax.tick_params(labelsize=200)" does not work for me, but "plt.tick_params(labelsize=200)" does. No idea why though. – Michael H Sep 27 '19 at 14:57
0

How about creating a colourbar in a separate figure?

Using the first example found here you can create a function:

import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt

def create_colourbar(cmap, vmin, vmax, label, save_path=None):
    ''' Creates colourbar in separate figure 
    :param cmap: Cmap string or object
    :param vmin: minimum value in data array
    :param vmax: maximum value in data array
    :param label: colourbar label
    :param save_path: Save path, optional
    '''

    fig, ax = plt.subplots(figsize=(5, 1))

    cb1 = mpl.colorbar.ColorbarBase(cmap=cmap,
                                    norm=Normalize(vmin=vmin,
                                                   vmax=vmax),
                                    orientation='horizontal', ax=ax)
    cb1.set_label(label, fontsize=6)
    plt.tight_layout()
    if save_path:
        plt.savefig(save_path3)
    plt.show()

where:

vmax = np.nanmax(world['LEADS'].values)
vmin = np.nanmin(world['LEADS'].values)

and cmap is a colormap string or object.

MoMiJi
  • 73
  • 1
  • 8