In a 4D-space, I want to compare different 2D slices of a scalar field (and later, do a bit of animation with this). Therefore, for the representations, which I choose te be colored contourf plots, I need to fix the absolute values for the correspondance between colors and values (further named "altitudes" with the geographic analogy of map making), therefore an "absolute" color palette, and its associated representation, the colorbar ; so that, whatever the altitude range specific to each slice, the colorbar, and the color-altitude correspondance will remain the same.
This is where I block : I can fix the color-altitude correspondance, but the colorbar seems to play by its own !
Here is a simplified code which shows the problem :
#!/usr/bin/env python3
## ColorAxis_lims.py
# CC:by-nc — ÉLw38fr (user:elw38fr), for StackExchange.com '200721.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib import colors
weSave = False
# 2D grid
xs = np.linspace(-2.0,2.0,81)
ys = np.linspace(-0.5,2.5,61)
xxs, yys = np.meshgrid(xs, ys)
# Rosenbrock function, made as a ridge
zzs = (1.-xxs)**2 + 100.*(yys-xxs*xxs)**2
AltiMax = 1.0
#AltiMax = 2.0
zzs = AltiMax * np.exp(-zzs)
# Making an extended color palette with constrasting endings
nCoul = 128
myColMap = cm.get_cmap('viridis', nCoul-2).colors
lightgreycyan = np.array([0.85,0.9,0.9,1.])
myColMap = np.vstack((lightgreycyan,myColMap)) # yellow side
lightgreypink = np.array([1.,0.5,0.5,1.])
myColMap = np.vstack((myColMap,lightgreypink)) # darl blue side
myColMap = colors.ListedColormap(myColMap)
# graphics
zMin, zMax = -0.5, 1.5
#zMin, zMax = 0., 1.
#zMin, zMax = 0.5, 0.9
plt.contourf(xs, ys, zzs, nCoul, vmin=zMin, vmax=zMax, cmap=myColMap)
plt.xlabel(f"( AltiMax = {AltiMax:.1f} )")
plt.title("Contourf for Rosenbrock in range [ {:.1f} — {:.1f} ]".\
format(zMin, zMax))
# clim & colorbar
cbMin, cbMax = -1., 2.
cbMin, cbMax = 0., 0.8
#cbMin, cbMax = 0., 1.
plt.clim(cbMin,cbMax)
clb = plt.colorbar(ticks=np.linspace(cbMin,cbMax,7))
# clb.set_clim(cbMin,cbMax) # deprecated
clb.set_label("clim({:.1f},{:.1f})".format(cbMin,cbMax))
if weSave: plt.savefig("ColorAxis_lims.py.Fig_2.png")
plt.show()
##
Ì hope that, even if you are a beginner in Python+Matplotlib, this should not be hard to decipher. The only "trick" is the use of an /augmented/ "viridis
" palette with two contrasted colors at the beginning and at the end, to help catching my problem (not only, but here it helps, I hope).
The redundant lines (some commented) are traces of my experiments, in case you are interested in playing with this code.
And my concerns :
- changing the values in the
contourf()
named parameters "vmin=
" & "vmax=
" makes no effect -- until you comment the "clim & colorbar" section --. Not really a true concern, but it puzzles me : what are they for ? - playing with the color limits, the constants "
cbMin
" & "cbMax
", has a great effect of thecontourf()
plot colors, on the colorbar graduation, but NOT on the range of represented "altitudes" in the (whole) colorbar : this range seems to depend only on the range of altitudes calculated from the represented "altitude" function values (the "AltiMax
" constant permits to experiment this) ; these "cbMin
" & "cbMax
" limits are of no use for what I want. :-(
What I want, which I did not solve :
- I want to fix the range of altitudes represented by the colorbar, whatever the represented "altitude" function. Long ago, this was what, hum ! the M4TL4B
caxis()
function was doing in that language… but neitherplt.clim()
nor the old (deprecated)clb.set_clim()
, do it.
... So that, when I'll do different maps, the "altitude" range representated by the colorbars will be constant.
Thanks in advance for any clues.