Центрировать палитру matplotlib по определенному значению

Я делаю графики, используя цветовую карту matplotlib "seismic", и хотел бы, чтобы белый цвет был центрирован на 0. Когда я запускаю свой скрипт без изменений, белый цвет падает с 0 до -10. Затем я попытался установить vmin = -50, vmax = 50, но в этом случае я полностью теряю белый цвет. Любые предложения о том, как этого добиться?

from netCDF4 import Dataset as NetCDFFile
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
nc = NetCDFFile('myfile.nc')
lat = nc.variables['lat'][:]
lon = nc.variables['lon'][:]
time = nc.variables['time'][:]
hgt = nc.variables['hgt'][:]
map = Basemap(llcrnrlon=180.,llcrnrlat=0.,urcrnrlon=320.,urcrnrlat=80.)
lons,lats = np.meshgrid(lon,lat)
x,y = map(lons,lats)
cs = map.contourf(x,y,hgt[0],cmap='seismic')
cbar = plt.colorbar(cs, orientation='horizontal', shrink=0.5, 
cmap='seismic')
cbar.set_label('500mb Geopotential Height Anomalies(m)')
map.drawcoastlines()
map.drawparallels(np.arange(20,80,20),labels=[1,1,0,0], linewidth=0.5)
map.drawmeridians(np.arange(200,320,20),labels=[0,0,0,1], linewidth=0.5)
plt.show()`

Участок со значениями по умолчанию

График с набором vmin, vmax

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
2 218
1

Ответы 1

Вы можете установить уровни, которые хотите показать, вручную. Пока у вас одинаковые интервалы слева и справа от нуля, это прекрасно работает.

levels = [-50,-40,-30,-20,-10,10,20,30,40,50]
ax.contourf(X,Y,Z, levels)

Пример:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-6.3,6.3)
y = np.linspace(-3.1,3.1)
X,Y = np.meshgrid(x,y)
Z = -np.cos(X)*np.cos(Y)*45

levels = [-50,-40,-30,-20,-10,10,20,30,40,50]
fig, ax = plt.subplots(figsize=(4,2))
cont = ax.contourf(X,Y,Z,levels, cmap = "seismic")
fig.colorbar(cont, orientation = "horizontal")
plt.show()

Или, если вы хотите, чтобы шкала цвета была пропорциональна данным,

fig.colorbar(cont, orientation = "horizontal", spacing = "proportional")

Если уровни не равны, нужно указать vmin и vmax.

levels = [-50,-40,-30,-20,-10,10,30,50,80,100]
cont = ax.contourf(X,Y,Z,levels, cmap = "seismic", vmin=-50, vmax=50)

Недостатком является то, что вы теряете разрешение, поэтому вы можете использовать BoundaryNorm для выбора цветов с одинаковым интервалом для неравномерных меток.

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

x = np.linspace(-6.3,6.3)
y = np.linspace(-3.1,3.1)
X,Y = np.meshgrid(x,y)
Z = -np.cos(X)*np.cos(Y)*45

levels = [-50,-40,-30,-20,-10,10,30,50,80,100]
norm = matplotlib.colors.BoundaryNorm(levels, len(levels)-1)
fig, ax = plt.subplots(figsize=(4,2))
cont = ax.contourf(X,Y,Z,levels,cmap=plt.get_cmap("seismic",len(levels)-1), norm=norm)
fig.colorbar(cont, orientation = "horizontal")
plt.show()

Чтобы изменить метки на шкале палитры так, чтобы они были отличными от уровней, или в случае, если они слишком велики, вы можете использовать аргумент ticks.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-6.3,6.3)
y = np.linspace(-3.1,3.1)
X,Y = np.meshgrid(x,y)
Z = -np.cos(X)*np.cos(Y)*45

levels = np.arange(-45,50,5)
levels = levels[levels!=0]
ticks=np.arange(-40,50,10)

fig, ax = plt.subplots(figsize=(4,2))
cont = ax.contourf(X,Y,Z,levels,cmap = "seismic", spacing = "proportional")
fig.colorbar(cont, orientation = "horizontal", ticks=ticks, spacing = "proportional")
plt.show()

Спасибо за подробный ответ. Явная установка уровней достигла того, что я хотел. Однако моя цветная полоса теперь показывает среднюю точку 0, а метки - каждые 15 единиц (-45, -30, -15,0,15,30,45). Как я могу указать, что метки шкалы цветов отображаются с шагом 10, от -50 до 50?

bayouwxman 14.03.2018 20:57

Ярлыки следуют за уровнями. Это показано в этом ответе.

ImportanceOfBeingErnest 14.03.2018 20:59

Хорошо .. Я установил свои уровни с интервалом 5, а метки шкалы палитры - с интервалами 15. Любой способ установить это значение с интервалом 10? Я попробовал пару вещей, которые нашел здесь, но пока не повезло.

bayouwxman 14.03.2018 21:14

@ImportanceOfBeingErnest после выделения norm с использованием BoundaryNorm, тогда разве нам не нужны vmin и vmax? Даже если я привожу аргумент vmin, vmax, он не меняет масштаб. Это потому, что шкала теперь выбрана на основе norm?

Light_B 10.01.2019 12:33

@Light_B Масштаб выбирается исходя из уровней. Цвета на шкале выбираются vmin/vmax или norm (я думаю, что если даны оба, норма должна иметь приоритет).

ImportanceOfBeingErnest 10.01.2019 12:36

Другие вопросы по теме