Я не можу отримати кольорову панель на таких графіках, як ця, щоб вона була такою ж висотою, що й графіка, окрім використання Photoshop після факту. Як домогтися відповідності висотам?
Я не можу отримати кольорову панель на таких графіках, як ця, щоб вона була такою ж висотою, що й графіка, окрім використання Photoshop після факту. Як домогтися відповідності висотам?
Відповіді:
Зробити це можна легко за допомогою matplotlib AxisDivider .
Приклад із пов’язаної сторінки також працює без використання субплотів:
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
, він відображатиметься поміщеним праворуч. Чи є спосіб подолати це?
Ця комбінація (і значення, близькі до цих), здається, "магічно" працює для мене, щоб кольорова смуга наблизилася до сюжету, незалежно від розміру екрана.
plt.colorbar(im,fraction=0.046, pad=0.04)
Він також не вимагає спільного використання осі, яка може дістати ділянку з квадрата.
im_ratio = data.shape[0]/data.shape[1]
plt.colorbar(im,fraction=0.046*im_ratio, pad=0.04)
де data
ваше зображення.
@bogatron вже дав відповідь, запропоновану документами matplotlib , що створює потрібну висоту, але це вводить іншу проблему. Тепер ширина кольорової смуги (а також простір між кольоровою смугою та сюжетом) змінюється з шириною сюжету. Іншими словами, співвідношення сторін кольорової панелі вже не фіксується.
Щоб отримати як потрібну висоту, так і задане співвідношення сторін, вам слід заглибитися трохи глибше в таємничий axes_grid1
модуль.
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)
Зауважте, що це визначає ширину кольорової смуги wt висоти ділянки (на відміну від ширини фігури, як це було раніше).
Тепер інтервал між кольоровою смугою та графіком може бути визначений як частка ширини кольорової смуги, що є IMHO набагато більш значущим числом, ніж частка ширини фігури.
ОНОВЛЕННЯ:
Я створив зошит IPython з цієї теми , куди я спакував вищезазначений код у легко повторну функціональну функцію:
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)
Його можна використовувати так:
im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)
Я ціную всі відповіді вище. Однак, як і деякі відповіді та коментарі вказали, axes_grid1
модуль може не адреса GeoAxes, тоді як регулювання fraction
, pad
, shrink
та інші подібні параметри можуть не обов'язково дати дуже точний порядок, який дійсно турбує мене. Я вважаю, що дати colorbar
власне axes
може бути кращим рішенням для вирішення всіх згаданих питань.
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)
Пізніше я знаходжу, що matplotlib.pyplot.colorbar
офіційна документація також дає ax
можливість, це наявні осі, які забезпечать місце для кольорової панелі. Тому це корисно для декількох підсплавів, див. Нижче.
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)
Знову ж таки, ви можете досягти подібних ефектів, вказавши cax, більш точний спосіб з моєї точки зору.
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)
Коли ви створюєте colorbar
спробу, використовуючи параметри дробу та / або зменшення.
З документів:
фракція 0,15; фракція оригінальних осей, яку слід використовувати для кольорової панелі
скорочуватися 1,0; фракція, за допомогою якої потрібно зменшити кольорову панель
colorbar()
функції чи методу.
Всі вищевикладені рішення хороші, але мені подобаються @ @ Стів і @ bejota найкращі, оскільки вони не передбачають вигадливих дзвінків і є універсальними.
Під універсальним я маю на увазі, що працює з будь-якими типами осей, в тому числі GeoAxes
. Наприклад, на нього ви спроектували осі для відображення:
projection = cartopy.crs.UTM(zone='17N')
ax = plt.axes(projection=projection)
im = ax.imshow(np.arange(200).reshape((20, 10)))
заклик до
cax = divider.append_axes("right", size=width, pad=pad)
не вдасться: KeyException: map_projection
Тому єдиним універсальним способом поводження з розміром кольорової панелі з усіма типами осей є:
ax.colorbar(im, fraction=0.046, pad=0.04)
Працюйте з дробом від 0,035 до 0,046, щоб отримати найкращий розмір. Однак значення для дробу та paddig потрібно буде коригувати, щоб найкраще підходити для вашого сюжету, і відрізнятимуться залежно від того, якщо орієнтація кольорової смуги знаходиться у вертикальному положенні чи горизонталі.
shrink
параметр, коли fraction
разом з pad
не дає достатньо бажаних результатів.