Выравнивание цветовой панели по краям подзаголовка GeoAxes

#python #python-3.x #matplotlib #cartopy

#python #python-3.x #matplotlib #картография

Вопрос:

У меня есть рисунок с 3 подзаголовками, два из которых имеют общую цветовую панель, а третий имеет собственную цветовую панель.

Я бы хотел, чтобы цветовые панели совпадали с вертикальными границами их соответствующих графиков, а для двух верхних графиков были одинаковые вертикальные границы.

Погуглив, я нашел способы сделать это с помощью одного графика, но застрял, пытаясь заставить его работать на моем рис. Моя фигура в настоящее время выглядит так:

введите описание изображения здесь

Код для которого выглядит следующим образом:

 import cartopy.io.shapereader as shpreader
import cartopy.crs as ccrs
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np


shpfilename = shpreader.natural_earth(resolution='50m',
                                      category='cultural',
                                      name='admin_0_countries')

reader = shpreader.Reader(shpfilename)

countries = reader.records()

projection = ccrs.PlateCarree()

fig = plt.figure()
axs = [plt.subplot(2, 2, x   1, projection = projection) for x in range(2)]
      [plt.subplot(2, 2, (3, 4), projection = projection)]


def cmap_seg(cmap, value, k):
    cmaplist = [cmap(i) for i in range(cmap.N)]
    cmap = mpl.colors.LinearSegmentedColormap.from_list(
                            'Custom cmap', cmaplist, cmap.N)
    bounds = np.linspace(0, k, k   1)
    norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
    color = cmap(norm(value))
    return color, cmap


for country in countries:
    
    c_name = country.attributes["SOVEREIGNT"]
    country_dat = df.loc[c_name]
    
    cmap = matplotlib.cm.get_cmap("plasma")
    cmap_blues = matplotlib.cm.get_cmap("Blues")
    ax_extent = [-170, 180, -65, 85]
    alpha = 1.0
    edgecolor = "k"
    linewidth = 0.5
    
    ax = axs[0]
    value = country_dat.loc["wgi_bin"]
    ax.add_geometries([country.geometry],
                    projection,
                    facecolor = cmap_seg(cmap, value, 5)[0],
                    alpha = alpha,
                    edgecolor = edgecolor,
                    linewidth = linewidth)
    ax.set_xlabel("WGI group")
    ax.set_extent(ax_extent)

    
    ax = axs[1]
    value = country_dat.loc["epi_bin"]
    ax.add_geometries([country.geometry],
                    projection,
                    facecolor = cmap_seg(cmap, value, 5)[0],
                    alpha = alpha,
                    edgecolor = edgecolor,
                    linewidth = linewidth)
    ax.set_xlabel("EPI group")
    ax.set_extent(ax_extent)
        
    
    ax = axs[2]
    value = country_dat.loc["diff"]
    ax.add_geometries([country.geometry],
                    projection,
                    facecolor = cmap_seg(cmap_blues, value, 4)[0],
                    alpha = alpha,
                    edgecolor = edgecolor,
                    linewidth = linewidth)
    ax.set_xlabel("difference")
    ax.set_extent(ax_extent)

subplot_labels = ["WGI group", "EPI group", "Metric difference"]

for i, ax in enumerate(axs):
    ax.text(0.5, -0.07, subplot_labels[i], va='bottom', ha='center',
        rotation='horizontal', rotation_mode='anchor',
        transform=ax.transAxes)
    
sm = plt.cm.ScalarMappable(cmap=cmap_seg(cmap, 5, 5)[1], norm = plt.Normalize(0, 5))
sm._A = []
cb = plt.colorbar(sm, ax = axs[1], values = [1,2,3,4, 5], ticks = [1,2,3,4,5])
                  
sm2 = plt.cm.ScalarMappable(cmap=cmap_seg(cmap_blues, 5, 4)[1], norm = plt.Normalize(0, 4))
sm2._A = []
cb2 = plt.colorbar(sm2, ax = axs[2], values = [0,1,2,3], ticks = [0,1,2,3])
 

Комментарии:

1. Цветовую панель можно настроить, указав с помощью опции shrink . Например, plt.colorbar(sm2, ax = axs[2], shrink=0.75, ...) . Значение 0.75 представляет длину 75% от нормального размера.

2. Вы также можете выровнять цветовую панель по фактической высоте осей. С возможностью определения местоположения осей. Я могу предоставить объяснение, если вы предоставите нам df

Ответ №1:

Попробуйте это:

 # update your code for this specific line (added shrink option)
cb = plt.colorbar(sm, ax=axs[1], values=[1,2,3,4,5], ticks=[1,2,3,4,5], shrink=0.6)
 

И добавьте эти строки кода ближе к концу:

 p00 = axs[0].get_position()
p01 = axs[1].get_position()
p00_new = [p00.x0, p01.y0, p00.width, p01.height]
axs[0].set_position(p00_new)
 

График должен быть похож на этот:

sample_output

Комментарии:

1. Спасибо за ваш ответ, я попробовал то, что вы предлагаете. Теперь рисунок намного ближе к тому, как я хочу!