如何在matplotlib绘图中遮罩某些值?

0 投票
1 回答
98 浏览
提问于 2025-04-14 17:41

我想在某个地图上绘制一些数值,但我不想绘制值为0的部分。我该怎么做呢?

fig = plt.figure(figsize=(16, 10))
ax = plt.axes(projection=ccrs.PlateCarree()
)
ax.set_extent([10, 20, 10, 20], crs=proj)

# reading data
ds  = xr.open_dataset(fname)
tqc = ds.tqc[0,:] 

# get lon and lat values
clon = np.rad2deg(ds.clon.values)
clat = np.rad2deg(ds.clat.values)

# creating plot
plt.tricontourf(clon, clat, tqc, cmap='magma_r')
colorbar_tqi = plt.colorbar(mpl.cm.ScalarMappable(norm=mpl.colors.Normalize(vmin=0, vmax=3.2), cmap='magma_r'),
             ax=ax, orientation='vertical', label='TQI [kg/m2]', pad = 0.01, shrink=.53)

另外,我还想知道怎么把颜色条的高度设置得和我的图形高度完全一致。我用了一种叫做缩放的方式,试了几个值来看看哪个最合适,但这似乎不是正确的方法。

编辑
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot()

# data
ds  = xr.open_dataset(fname)
tqc = ds.tqc[0,:]

# lon und lat to degrees
clon = np.rad2deg(ds.clon.values)
clat = np.rad2deg(ds.clat.values)

# create boolean
keep_bool = tqc.values > 0.05

clon = clon[keep_bool]
clat = clat[keep_bool]
tqc_masked = tqc[keep_bool]

# plot
mappable = ax.tricontourf(clon, clat, tqc_masked, cmap='plasma', vmin=0.5, vmax=3.2)
fig.colorbar(mappable, pad=0.01, label='TQC [kg/m$^2$]')

但我遇到了以下问题:首先,vmin和vmax不起作用,其次,掩膜给我带来了一个“值错误:z数组的长度必须和三角剖分的x和y数组相同”。我检查过了,tqc、clon和clat在掩膜前后形状是一样的。

编辑 2

换句话说,我想复现以下代码:

fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot()

# data
ds  = xr.open_dataset(fname)
tqc = ds.tqc[0,:]

# lon und lat to degrees
clon = np.rad2deg(ds.clon.values)
clat = np.rad2deg(ds.clat.values)

# plot
boundaries = [0.2, 0.4, 0.6, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8]
colors = ('#c4c4e4','#8989c9','#4e4eaf','#141494','#272776','#626256','#9d9d35','#d8d815') #,'#f6eb00','#dbb100','#c17600','#a63b00','#8b0000')
mappable = ax.tricontourf(clon, clat, tqc, colors=colors, levels=boundaries)
fig.colorbar(mappable, pad=0.01, label='TQC [kg/m$^2$]')

并得到以下结果:

TQC plottet with boundaries explicitly set 但我不想明确设置边界和颜色。我只想掩膜所有小于0.2的值,并用某种颜色映射绘制其他值。但如果我使用掩膜

fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot()

# data
ds  = xr.open_dataset(fname)
tqc = ds.tqc[0,:]

# lon und lat to degrees
clon = np.rad2deg(ds.clon.values)
clat = np.rad2deg(ds.clat.values)

# create boolean
keep_bool = tqc.values > 0.2

clon = clon[keep_bool]
clat = clat[keep_bool]
tqc_masked = tqc.values[keep_bool]

# plot
mappable = ax.tricontourf(clon, clat, tqc_masked, cmap='plasma')
fig.colorbar(mappable, pad=0.01, label='TQC [kg/m$^2$]')

它并没有掩膜小于0.2的值。

same output but with masking

编辑 3

这仍然对我不起作用 :( 我真的不知道为什么,但使用不同的mask_below值时看起来很奇怪。我使用的代码是:

# data
ds  = xr.open_dataset(fname)
tqc = ds.tqc[0,:]

# lon und lat to degrees
clon = np.rad2deg(ds.clon.values)
clat = np.rad2deg(ds.clat.values)

# create boolean
mask_below = 0.2

#Define a colormap where values <= vmin are white
cmap = plt.get_cmap('plasma')
cmap.set_under('white')

#Plot
fig = plt.figure(figsize=(8, 4))
ax = fig.add_subplot()

mappable = ax.tricontourf(clon, clat, tqc, cmap=cmap, vmin=mask_below)
cbar = fig.colorbar(mappable, label='TQI (kg/m$^2$)')

#Adjust the colour bar limits to remove the masked values
mask_above = cbar.ax.get_ylim()[1]
cbar.ax.set_ylim(mask_below, mask_above)

#Extra formatting: labels and spines
ax.set(xlabel='clon', ylabel='clat')
ax.spines[:].set_visible(False)

如果我设置mask_below=0.2,它并没有掩膜小于0.2的值:

masking_error

而如果我使用其他值,比如mask_below=0.35,它会掩膜一些值,但不会调整颜色条:

colorbar_error

xarray.DataArray
ncells_dim=100
clon=np.array([0.5111043 , 0.5123288 , 0.51195335, 0.512205  , 0.51355225,
       0.51477456, 0.51440084, 0.5146535 , 0.5142793 , 0.5130547 ,
       0.5134298 , 0.51317763, 0.51330703, 0.51453215, 0.5141575 ,
       0.51441056, 0.5140354 , 0.512808  , 0.5131841 , 0.5129315 ,
       0.5115795 , 0.51035   , 0.5107277 , 0.51047623, 0.5108535 ,
       0.51208085, 0.51170444, 0.51195645, 0.511829  , 0.51060224,
       0.51097906, 0.510728  , 0.5091193 , 0.5078875 , 0.50826705,
       0.5080166 , 0.5066546 , 0.5054207 , 0.5058019 , 0.5055526 ,
       0.50593334, 0.507165  , 0.50678515, 0.507035  , 0.5069154 ,
       0.5056842 , 0.5060645 , 0.5058155 , 0.5061953 , 0.5074242 ,
       0.50704527, 0.5072948 , 0.508652  , 0.5098787 , 0.5095015 ,
       0.50975204, 0.5093744 , 0.50814545, 0.50852394, 0.50827396,
       0.5083956 , 0.50962514, 0.509247  , 0.50949794, 0.5096283 ,
       0.50840217, 0.5087797 , 0.5085301 , 0.5071749 , 0.5059466 ,
       0.50632584, 0.5060773 , 0.5064561 , 0.5076822 , 0.5073042 ,
       0.50755334, 0.50743324, 0.5062077 , 0.506586  , 0.5063378 ,
       0.5056702 , 0.50690466, 0.5065238 , 0.50677407, 0.5081381 ,
       0.5093704 , 0.5089913 , 0.5092426 , 0.508863  , 0.5076284 ,
       0.5080089 , 0.5077581 , 0.5078794 , 0.5091145 , 0.5087344 ,
       0.5089861 , 0.51060164, 0.51183176, 0.51145434, 0.51170677],
      dtype=np.float32)
clat=np.array([1.1715792, 1.1713854, 1.1716133, 1.1718533, 1.1711911, 1.1709963,
       1.1712245, 1.1714643, 1.1716925, 1.1718872, 1.171659 , 1.1714191,
       1.1721269, 1.1719323, 1.1721605, 1.1724002, 1.1726284, 1.172823 ,
       1.1725948, 1.172355 , 1.173017 , 1.1732106, 1.1729827, 1.1727428,
       1.1725149, 1.1723211, 1.1725491, 1.172789 , 1.1720812, 1.172275 ,
       1.172047 , 1.1718072, 1.1734039, 1.1735966, 1.1733688, 1.1731288,
       1.1737889, 1.1739807, 1.1737531, 1.1735132, 1.1732855, 1.1730936,
       1.1733212, 1.1735612, 1.1728535, 1.1730455, 1.1728178, 1.1725779,
       1.1723502, 1.1721581, 1.1723858, 1.1726258, 1.1719656, 1.1717726,
       1.1720005, 1.1722404, 1.1724683, 1.1726612, 1.1724334, 1.1721934,
       1.172901 , 1.1727082, 1.1729361, 1.1731759, 1.1715326, 1.1717256,
       1.1714978, 1.1712577, 1.171918 , 1.1721101, 1.1718825, 1.1716424,
       1.1714147, 1.1712226, 1.1714503, 1.1716903, 1.1709825, 1.1711746,
       1.170947 , 1.1707069, 1.1742207, 1.1740289, 1.1742566, 1.1744964,
       1.1738365, 1.1736437, 1.1738715, 1.1741114, 1.1743393, 1.1745319,
       1.1743041, 1.1740643, 1.1747718, 1.1745791, 1.174807 , 1.1750468,
       1.1734505, 1.1732569, 1.1734848, 1.1737247], dtype=np.float32)
tqc_values=np.array([0.15569663, 0.11916991, 0.11858897, 0.10107199, 0.15579152,
       0.13194141, 0.14021584, 0.11554057, 0.0784738 , 0.07480974,
       0.09887432, 0.12334369, 0.0665338 , 0.0794786 , 0.06426689,
       0.05735027, 0.09237053, 0.11770064, 0.12878077, 0.11895558,
       0.13666902, 0.16525495, 0.13639313, 0.128966  , 0.12359453,
       0.12086542, 0.14622061, 0.13807052, 0.09360459, 0.13403493,
       0.11391085, 0.12349615, 0.11537005, 0.12506713, 0.08103316,
       0.08701873, 0.15411958, 0.17143962, 0.14882892, 0.10075304,
       0.05091187, 0.07667481, 0.06803349, 0.12026618, 0.09903781,
       0.04676978, 0.08345287, 0.11008713, 0.12116196, 0.10179084,
       0.10546485, 0.09939726, 0.11531032, 0.14638193, 0.12827232,
       0.12819426, 0.0956176 , 0.11703059, 0.08874848, 0.09444176,
       0.1384329 , 0.11361963, 0.12464031, 0.14904864, 0.1392543 ,
       0.11825788, 0.11579482, 0.09708434, 0.13313244, 0.1233273 ,
       0.1366036 , 0.13449918, 0.11231212, 0.08745293, 0.10871083,
       0.11593907, 0.08150337, 0.10770909, 0.1069753 , 0.10310051,
       0.15952688, 0.17038634, 0.15969357, 0.10159207, 0.13086197,
       0.09630024, 0.12349406, 0.09031961, 0.11969905, 0.07538784,
       0.12515202, 0.16452919, 0.07986163, 0.1322178 , 0.12553921,
       0.12195621, 0.16712797, 0.1502901 , 0.1711053 , 0.14726645],
      dtype=np.float32)
time=np.datetime64('2024-02-02T21:00:00.000000000')

# Create the DataArray with coordinates and attributes
tqc_dataarray = xr.DataArray(
    data=tqc_values,
    dims=["ncells",],
    coords=dict(
        time=time,
        clon=('ncells', clon),
        clat=('ncells', clat)
    ),
    attrs=dict(
        standard_name='tqc',
        long_name='total column integrated cloud water',
        units='kg m-2'
    ),
    name='tqc'
)

1 个回答

0

在下面的代码中,低于 mask_below 的值被涂成白色,这样看起来就像被遮住了一样。这个效果是通过使用 .set_under("white")vmin= 来把这些值映射成白色来实现的。同时,颜色条的刻度和范围也进行了调整,以隐藏颜色条上白色的部分。

在这里输入图片描述

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

clon=np.array([0.5111043 , 0.5123288 , 0.51195335, 0.512205  , 0.51355225,
       0.51477456, 0.51440084, 0.5146535 , 0.5142793 , 0.5130547 ,
       0.5134298 , 0.51317763, 0.51330703, 0.51453215, 0.5141575 ,
       0.51441056, 0.5140354 , 0.512808  , 0.5131841 , 0.5129315 ,
       0.5115795 , 0.51035   , 0.5107277 , 0.51047623, 0.5108535 ,
       0.51208085, 0.51170444, 0.51195645, 0.511829  , 0.51060224,
       0.51097906, 0.510728  , 0.5091193 , 0.5078875 , 0.50826705,
       0.5080166 , 0.5066546 , 0.5054207 , 0.5058019 , 0.5055526 ,
       0.50593334, 0.507165  , 0.50678515, 0.507035  , 0.5069154 ,
       0.5056842 , 0.5060645 , 0.5058155 , 0.5061953 , 0.5074242 ,
       0.50704527, 0.5072948 , 0.508652  , 0.5098787 , 0.5095015 ,
       0.50975204, 0.5093744 , 0.50814545, 0.50852394, 0.50827396,
       0.5083956 , 0.50962514, 0.509247  , 0.50949794, 0.5096283 ,
       0.50840217, 0.5087797 , 0.5085301 , 0.5071749 , 0.5059466 ,
       0.50632584, 0.5060773 , 0.5064561 , 0.5076822 , 0.5073042 ,
       0.50755334, 0.50743324, 0.5062077 , 0.506586  , 0.5063378 ,
       0.5056702 , 0.50690466, 0.5065238 , 0.50677407, 0.5081381 ,
       0.5093704 , 0.5089913 , 0.5092426 , 0.508863  , 0.5076284 ,
       0.5080089 , 0.5077581 , 0.5078794 , 0.5091145 , 0.5087344 ,
       0.5089861 , 0.51060164, 0.51183176, 0.51145434, 0.51170677],
      dtype=np.float32)
clat=np.array([1.1715792, 1.1713854, 1.1716133, 1.1718533, 1.1711911, 1.1709963,
       1.1712245, 1.1714643, 1.1716925, 1.1718872, 1.171659 , 1.1714191,
       1.1721269, 1.1719323, 1.1721605, 1.1724002, 1.1726284, 1.172823 ,
       1.1725948, 1.172355 , 1.173017 , 1.1732106, 1.1729827, 1.1727428,
       1.1725149, 1.1723211, 1.1725491, 1.172789 , 1.1720812, 1.172275 ,
       1.172047 , 1.1718072, 1.1734039, 1.1735966, 1.1733688, 1.1731288,
       1.1737889, 1.1739807, 1.1737531, 1.1735132, 1.1732855, 1.1730936,
       1.1733212, 1.1735612, 1.1728535, 1.1730455, 1.1728178, 1.1725779,
       1.1723502, 1.1721581, 1.1723858, 1.1726258, 1.1719656, 1.1717726,
       1.1720005, 1.1722404, 1.1724683, 1.1726612, 1.1724334, 1.1721934,
       1.172901 , 1.1727082, 1.1729361, 1.1731759, 1.1715326, 1.1717256,
       1.1714978, 1.1712577, 1.171918 , 1.1721101, 1.1718825, 1.1716424,
       1.1714147, 1.1712226, 1.1714503, 1.1716903, 1.1709825, 1.1711746,
       1.170947 , 1.1707069, 1.1742207, 1.1740289, 1.1742566, 1.1744964,
       1.1738365, 1.1736437, 1.1738715, 1.1741114, 1.1743393, 1.1745319,
       1.1743041, 1.1740643, 1.1747718, 1.1745791, 1.174807 , 1.1750468,
       1.1734505, 1.1732569, 1.1734848, 1.1737247], dtype=np.float32)
tqc_values=np.array([0.15569663, 0.11916991, 0.11858897, 0.10107199, 0.15579152,
       0.13194141, 0.14021584, 0.11554057, 0.0784738 , 0.07480974,
       0.09887432, 0.12334369, 0.0665338 , 0.0794786 , 0.06426689,
       0.05735027, 0.09237053, 0.11770064, 0.12878077, 0.11895558,
       0.13666902, 0.16525495, 0.13639313, 0.128966  , 0.12359453,
       0.12086542, 0.14622061, 0.13807052, 0.09360459, 0.13403493,
       0.11391085, 0.12349615, 0.11537005, 0.12506713, 0.08103316,
       0.08701873, 0.15411958, 0.17143962, 0.14882892, 0.10075304,
       0.05091187, 0.07667481, 0.06803349, 0.12026618, 0.09903781,
       0.04676978, 0.08345287, 0.11008713, 0.12116196, 0.10179084,
       0.10546485, 0.09939726, 0.11531032, 0.14638193, 0.12827232,
       0.12819426, 0.0956176 , 0.11703059, 0.08874848, 0.09444176,
       0.1384329 , 0.11361963, 0.12464031, 0.14904864, 0.1392543 ,
       0.11825788, 0.11579482, 0.09708434, 0.13313244, 0.1233273 ,
       0.1366036 , 0.13449918, 0.11231212, 0.08745293, 0.10871083,
       0.11593907, 0.08150337, 0.10770909, 0.1069753 , 0.10310051,
       0.15952688, 0.17038634, 0.15969357, 0.10159207, 0.13086197,
       0.09630024, 0.12349406, 0.09031961, 0.11969905, 0.07538784,
       0.12515202, 0.16452919, 0.07986163, 0.1322178 , 0.12553921,
       0.12195621, 0.16712797, 0.1502901 , 0.1711053 , 0.14726645],
      dtype=np.float32)

ds = pd.DataFrame({'clon': clon, 'clat': clat, 't': tqc_values})

# Lat and long to degrees
clon = np.rad2deg(ds.clon.values)
clat = np.rad2deg(ds.clat.values)
mask_below = 0.10

#Define a colormap where values <= vmin are white
cmap = plt.get_cmap('plasma')
cmap.set_under('white')

#Plot
fig = plt.figure(figsize=(8, 4))
ax = fig.add_subplot()

ax.scatter(clon, clat, marker='^', s=15, c='black', zorder=2)
mappable = ax.tricontourf(clon, clat, ds.t.values, cmap=cmap, vmin=mask_below)
cbar = fig.colorbar(mappable, label='TQI (kg/m$^2$)')

#Adjust the colour bar limits to remove the masked values
from matplotlib import ticker
prev_levels = mappable.levels
new_levels = prev_levels[prev_levels > mask_below]
new_levels = np.insert(new_levels, 0, mask_below)
cbar.ax.yaxis.set_major_locator(ticker.FixedLocator(new_levels))
cbar.ax.set_ylim(mask_below, mappable.levels[-1])

#Extra formatting: labels and spines
ax.set(xlabel='clon', ylabel='clat')
ax.spines[:].set_visible(False)

撰写回答