Reputation: 626
I know set_bad can colour the pixel into a specific colour but in my example I only want to have edge colour for blue and grey pixels with values and not the bad pixels (red)
import matplotlib.pyplot as plt
import xarray as xr
import numpy as np
from matplotlib import colors
fig, ax = plt.subplots(1, 1, figsize=(12, 8))
# provide example data array with a mixture of floats and nans in them
data = xr.DataArray([np.random.rand(10, 10)]) # Example data
# set a few nans
data[0, 1, 1] = np.nan
data[0, 1, 2] = np.nan
data[0, 1, 3] = np.nan
data[0, 2, 1] = np.nan
data[0, 2, 2] = np.nan
data[0, 2, 3] = np.nan
data[0, 3, 1] = np.nan
data[0, 3, 2] = np.nan
data[0, 3, 3] = np.nan
cmap = colors.ListedColormap(['#2c7bb6', "#999999"])
# make nan trends invalid and set edgecolour to white
cmap.set_bad(color = 'red')
data.plot(edgecolor = "grey", cmap = cmap)
Upvotes: 1
Views: 51
Reputation: 6482
Update:
I was premature in my original answer (see below), and you can actually pass a list of edge colours (see pcolormesh
) that can be used for each "box" within the plot. So, you could use:
import xarray as xr
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import colors
fig, ax = plt.subplots(1, 1, figsize=(12, 8))
# provide example data array with a mixture of floats and nans in them
data = xr.DataArray([np.random.rand(10, 10)]) # Example data
# set a few nans
data[0, 1, 1] = np.nan
data[0, 1, 2] = np.nan
data[0, 1, 3] = np.nan
data[0, 2, 1] = np.nan
data[0, 2, 2] = np.nan
data[0, 2, 3] = np.nan
data[0, 3, 1] = np.nan
data[0, 3, 2] = np.nan
data[0, 3, 3] = np.nan
# get edgecolors - "grey" for good values red for "bad"
edgecolors = [
"grey" if np.isfinite(c) else "red" # could also just have "none"
for c in data.values.flatten()
]
cmap = colors.ListedColormap(['#2c7bb6', "#999999"])
cmap.set_bad("red")
data.plot(edgecolors=edgecolors, cmap = cmap)
plt.show()
I'm afraid you can't remove the edge color from only around the "bad" values, but what you can do is overplot the bad values without any edge color set. E.g.,
import xarray as xr
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import colors
fig, ax = plt.subplots(1, 1, figsize=(12, 8))
# provide example data array with a mixture of floats and nans in them
data = xr.DataArray([np.random.rand(10, 10)]) # Example data
# set a few nans
data[0, 1, 1] = np.nan
data[0, 1, 2] = np.nan
data[0, 1, 3] = np.nan
data[0, 2, 1] = np.nan
data[0, 2, 2] = np.nan
data[0, 2, 3] = np.nan
data[0, 3, 1] = np.nan
data[0, 3, 2] = np.nan
data[0, 3, 3] = np.nan
cmap = colors.ListedColormap(['#2c7bb6', "#999999"])
data.plot(edgecolors="grey", cmap = cmap)
# get new array of "bad" values with values of 1 and non-bad values with values of NaN
data_bad = xr.where(data.isnull(), 1.0, np.nan)
ax = plt.gca()
# plot "bad" values as red without any edge color
cmap_bad = colors.ListedColormap(["red"])
data_bad.plot(ax=ax, edgecolors="none", cmap=cmap_bad, add_colorbar=False)
plt.show()
Upvotes: 3