proplot-dev / proplot

🎨 A succinct matplotlib wrapper for making beautiful, publication-quality graphics
https://proplot.readthedocs.io
MIT License
1.07k stars 96 forks source link

Question: is it possible to place colorbars into an empty axis without messing up the spacing between other subplots? #457

Closed Eisbrenner closed 2 days ago

Eisbrenner commented 3 weeks ago

Hi,

I was wondering if I can put colorbars into a place where I have an axis free without messing up the spacing between other subplots (see example image and code below)?

A) original (as put out by the code below) Pasted image

B) desired version (if somewhat similar is good enough, maybe someone has a better idea as what I am trying) Pasted image

Thanks! Ezra

import proplot as pplt
import numpy as np

pplt.rc["figure.facecolor"] = "white"

coord_transform = 360
lon_0 = -50
lat_0 = 10

pplt.rc.reso = "hi"

lower = 1
nrows = 2 + lower
ncols = 3

fig = pplt.figure(figwidth="190mm")
gs = pplt.GridSpec(ncols=ncols, nrows=nrows)

geo_axs = [
    fig.subplot(
        gs[j, i],
    )
    for j, i in [
        (1, 0),
        (1, 1),
        (0, 2),
        (1, 2),
    ]
]
empty_axs = [fig.subplot(gs[j, i]) for j, i in [
        (0, 0),
        (0, 1),
    ]]
[ax.axis("off") for ax in empty_axs]

[ax.format(abc="A", abcloc="ul", abcbbox=True) for ax in geo_axs]

cbar_handles = {}
a = np.linspace(-1, 1)
T = np.outer(a, a)
cbar_handles[1] = geo_axs[0].contourf(T)
cbar_scatter = geo_axs[1].contourf(T)
cbar_handles[2] = geo_axs[2].contourf(T)

for latlabels, lonlabels, ax in zip(["l", "", "r", "r"], ["b", "b", "", "b"], geo_axs):
    ax.format(
        gridminor=True,
    )

empty_axs[0].colorbar(
    cbar_handles[1],
    loc="l",
    label="Temperature (\N{DEGREE SIGN}C)",
    ticks=0.5,
)
empty_axs[0].colorbar(
    cbar_scatter,
    loc="l",
    label="Bleaching (%)",
    ticks=20,
)
empty_axs[0].colorbar(
    cbar_handles[2],
    loc="l",
    label="Temperature difference (\N{DEGREE SIGN}C)",
    ticks=0.5,
)

ax = fig.subplot(
    gs[-lower:, :],
)
ax.format(abc="A", abcloc="ul", abcbbox=True, xticks=2)

color = pplt.scale_luminance("red9", 1.5)

px = ax.panel("t", space=0.5)
px.format(
    yticks=100,
    ylabelloc="right",
    ylabel="surveys",
    yticklabelloc="right",
    ytickloc="right",
    titleloc="ur",
)
gepcel commented 1 day ago

Have you got any solution?

gepcel commented 1 day ago

There maybe a bad way to do this,. image

import proplot as pplt
import numpy as np

pplt.rc["figure.facecolor"] = "white"

coord_transform = 360
lon_0 = -50
lat_0 = 10

pplt.rc.reso = "hi"

lower = 1
nrows = 2 + lower
ncols = 3

fig = pplt.figure(figwidth="190mm")
gs = pplt.GridSpec(ncols=ncols, nrows=nrows)

geo_axs = [
    fig.subplot(
        gs[j, i],
    )
    for j, i in [
        (1, 0),
        (1, 1),
        (0, 2),
        (1, 2),
    ]
]
empty_axs = fig.subplot(gs[0, :2])
empty_axs.axis("off")

[ax.format(abc="A", abcloc="ul", abcbbox=True) for ax in geo_axs]

cbar_handles = {}
a = np.linspace(-1, 1)
T = np.outer(a, a)
cbar_handles[1] = geo_axs[0].contourf(T)
cbar_scatter = geo_axs[1].contourf(T)
cbar_handles[2] = geo_axs[2].contourf(T)

for latlabels, lonlabels, ax in zip(["l", "", "r", "r"], ["b", "b", "", "b"], geo_axs):
    ax.format(
        gridminor=True,
    )

ix_temperature = empty_axs.inset((.95, 0, .05, 1), transform='axes', zoom=False)
m = ix_temperature.colorbar(
    cbar_handles[1],
    loc="fill",
    width=0.1,
    orientation='vertical',
    label="Temperature (\N{DEGREE SIGN}C)",
    ticks=0.5,
)

ix_bleaching = empty_axs.inset((.75, 0, .05, 1), transform='axes', zoom=False)

ix_bleaching.colorbar(
    cbar_scatter,
    loc="fill",
    label="Bleaching (%)",
    ticks=20,
    orientation='vertical',
)
ix_temperature_difference = empty_axs.inset((.57, 0, .05, 1), transform='axes', zoom=False)

ix_temperature_difference.colorbar(
    cbar_handles[2],
    loc="fill",
    label="Temperature difference (\N{DEGREE SIGN}C)",
    ticks=0.5,
    orientation='vertical',
)

ax = fig.subplot(
    gs[-lower:, :],
)
ax.format(abc="A", abcloc="ul", abcbbox=True, xticks=2)

color = pplt.scale_luminance("red9", 1.5)

px = ax.panel("t", space=0.5)
px.format(
    yticks=100,
    ylabelloc="right",
    ylabel="surveys",
    yticklabelloc="right",
    ytickloc="right",
    titleloc="ur",
)