Nie mogę sprawić, aby pasek kolorów na wykresach imshow, takich jak ten, miał taką samą wysokość jak wykres, z wyjątkiem użycia Photoshopa po fakcie. Jak dopasować wysokości?
Nie mogę sprawić, aby pasek kolorów na wykresach imshow, takich jak ten, miał taką samą wysokość jak wykres, z wyjątkiem użycia Photoshopa po fakcie. Jak dopasować wysokości?
Odpowiedzi:
Możesz to łatwo zrobić za pomocą AxisDivider matplotlib .
Przykład ze strony, do której prowadzi łącze, działa również bez korzystania z wykresów podrzędnych:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
plt.figure()
ax = plt.gca()
im = ax.imshow(np.arange(100).reshape((10,10)))
# create an axes on the right side of ax. The width of cax will be 5%
# of ax and the padding between cax and ax will be fixed at 0.05 inch.
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
plt.title
, zostanie on zamieniony na prawo. Czy istnieje sposób, aby to przezwyciężyć?
Ta kombinacja (i zbliżone do nich wartości) wydaje mi się „magicznie” działać, utrzymując pasek kolorów skalowany do wykresu, niezależnie od rozmiaru wyświetlacza.
plt.colorbar(im,fraction=0.046, pad=0.04)
Nie wymaga również współdzielenia osi, która może wyprowadzić wykres z kwadratu.
im_ratio = data.shape[0]/data.shape[1]
plt.colorbar(im,fraction=0.046*im_ratio, pad=0.04)
gdzie data
jest twój obraz.
@bogatron udzielił już odpowiedzi sugerowanej przez dokumentację matplotlib , która daje odpowiednią wysokość, ale wprowadza inny problem. Teraz szerokość paska kolorów (jak również przestrzeń między paskiem kolorów a wykresem) zmienia się wraz z szerokością wykresu. Innymi słowy, współczynnik kształtu paska kolorów nie jest już ustalony.
Aby uzyskać zarówno odpowiednią wysokość, jak i dane proporcje, musisz zagłębić się nieco w tajemniczy axes_grid1
moduł.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size
import numpy as np
aspect = 20
pad_fraction = 0.5
ax = plt.gca()
im = ax.imshow(np.arange(200).reshape((20, 10)))
divider = make_axes_locatable(ax)
width = axes_size.AxesY(ax, aspect=1./aspect)
pad = axes_size.Fraction(pad_fraction, width)
cax = divider.append_axes("right", size=width, pad=pad)
plt.colorbar(im, cax=cax)
Zwróć uwagę, że określa to szerokość paska kolorów w stosunku do wysokości wykresu (w przeciwieństwie do szerokości figury, tak jak było wcześniej).
Odstęp między paskiem kolorów a wykresem można teraz określić jako ułamek szerokości paska kolorów, co jest liczbą IMHO o wiele bardziej znaczącą niż ułamek szerokości figury.
AKTUALIZACJA:
Stworzyłem notatnik IPython na ten temat , w którym spakowałem powyższy kod do łatwej do ponownego wykorzystania funkcji:
import matplotlib.pyplot as plt
from mpl_toolkits import axes_grid1
def add_colorbar(im, aspect=20, pad_fraction=0.5, **kwargs):
"""Add a vertical color bar to an image plot."""
divider = axes_grid1.make_axes_locatable(im.axes)
width = axes_grid1.axes_size.AxesY(im.axes, aspect=1./aspect)
pad = axes_grid1.axes_size.Fraction(pad_fraction, width)
current_ax = plt.gca()
cax = divider.append_axes("right", size=width, pad=pad)
plt.sca(current_ax)
return im.axes.figure.colorbar(im, cax=cax, **kwargs)
Można go używać w następujący sposób:
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
Doceniam wszystkie powyższe odpowiedzi. Jednak, podobnie jak niektóre odpowiedzi i komentarze zauważono, axes_grid1
moduł może nie GeoAxes adres, a regulacja fraction
, pad
, shrink
, i inne podobne parametry mogą niekoniecznie dają bardzo dokładny porządek, który naprawdę mnie martwi. Uważam, że dając colorbar
jej własny axes
może być lepszym rozwiązaniem, aby rozwiązać wszystkie problemy, które zostały wymienione.
import matplotlib.pyplot as plt
import numpy as np
fig=plt.figure()
ax = plt.axes()
im = ax.imshow(np.arange(100).reshape((10,10)))
# Create an axes for colorbar. The position of the axes is calculated based on the position of ax.
# You can change 0.01 to adjust the distance between the main image and the colorbar.
# You can change 0.02 to adjust the width of the colorbar.
# This practice is universal for both subplots and GeoAxes.
cax = fig.add_axes([ax.get_position().x1+0.01,ax.get_position().y0,0.02,ax.get_position().height])
plt.colorbar(im, cax=cax) # Similar to fig.colorbar(im, cax = cax)
Później znajduję również matplotlib.pyplot.colorbar
oficjalną dokumentacjęax
opcję, czyli istniejące osie, które zapewnią miejsce na pasek kolorów. Dlatego jest przydatna w przypadku wielu wykresów pomocniczych, patrz poniżej.
fig, ax = plt.subplots(2,1,figsize=(12,8)) # Caution, figsize will also influence positions.
im1 = ax[0].imshow(np.arange(100).reshape((10,10)), vmin = -100, vmax =100)
im2 = ax[1].imshow(np.arange(-100,0).reshape((10,10)), vmin = -100, vmax =100)
fig.colorbar(im1, ax=ax)
Ponownie, możesz również osiągnąć podobne efekty, określając cax, dokładniej z mojej perspektywy.
fig, ax = plt.subplots(2,1,figsize=(12,8))
im1 = ax[0].imshow(np.arange(100).reshape((10,10)), vmin = -100, vmax =100)
im2 = ax[1].imshow(np.arange(-100,0).reshape((10,10)), vmin = -100, vmax =100)
cax = fig.add_axes([ax[1].get_position().x1-0.25,ax[1].get_position().y0,0.02,ax[0].get_position().y1-ax[1].get_position().y0])
fig.colorbar(im1, cax=cax)
Podczas tworzenia colorbar
próby użyj parametrów fraction i / lub shrink.
Z dokumentów:
frakcja 0,15; ułamek oryginalnych osi do użycia w pasku kolorów
zmniejszyć 1,0; ułamek, o który należy zmniejszyć pasek kolorów
colorbar()
funkcji lub metody.
Wszystkie powyższe rozwiązania są dobre, ale najbardziej lubię @ Steve i @ bejota, ponieważ nie wymagają wyszukanych połączeń i są uniwersalne.
Przez uniwersalny rozumiem, że działa z każdym typem osi, w tym GeoAxes
. Na przykład, jeśli masz rzutowane osie do mapowania:
projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))
wezwanie do
cax = divider.append_axes("right", size=width, pad=pad)
zawiedzie z: KeyException: map_projection
Dlatego jedynym uniwersalnym sposobem radzenia sobie z rozmiarem paska kolorów dla wszystkich typów osi jest:
ax.colorbar(im, fraction=0.046, pad=0.04)
Pracuj z ułamkiem od 0,035 do 0,046, aby uzyskać najlepszy rozmiar. Jednak wartości frakcji i paddig będą musiały zostać dostosowane, aby uzyskać najlepsze dopasowanie do wykresu i będą się różnić w zależności od tego, czy orientacja paska kolorów jest w pozycji pionowej, czy poziomej.
shrink
parametr, gdy fraction
razem z pad
nie dają one pożądanych rezultatów.