【问题标题】:Center matplotlib colormap on a specific value以特定值居中 matplotlib 颜色图
【发布时间】:2018-03-14 16:24:53
【问题描述】:

我正在使用 matplotlib 颜色图“地震”绘制绘图,并希望白色以 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()`

Plot with defaults

Plot with vmin, vmax set

【问题讨论】:

    标签: python python-3.x matplotlib colormap


    【解决方案1】:

    您可以手动设置要显示的级别。只要您在零的左侧和右侧具有相同的间隔间距,就可以很好地工作。

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

    例子:

    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")
    

    如果级别不等,则需要指定vminvmax

    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?
    • 标签跟随级别。这显示在这个答案中。
    • OK..我将级别设置为 5 的间隔,而颜色条标签的间隔为 15。有什么方法可以强制将其设置为 10 的间隔?我尝试了一些在这里找到的东西,但还没有运气。
    • @ImportanceOfBeingErnest 在使用BoundaryNorm 分配norm 之后,我们是否不需要vminvmax?即使我给出vminvmax 的论点,它也不会改变比例。是不是因为现在是根据norm来选择尺度的?
    • @Light_B 根据级别选择比例。刻度上的颜色由vmin/vmaxnorm 选择(我认为如果两者都给出,则规范应该优先)。
    猜你喜欢
    • 1970-01-01
    • 2015-08-08
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2016-05-14
    • 2013-12-24
    • 1970-01-01
    相关资源
    最近更新 更多