Set Colorbar Range in matplotlib
Using vmin
and vmax
forces the range for the colors. Here's an example:
import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np
cdict = {
'red' : ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
'green': ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
'blue' : ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}
cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)
x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)
data = 2*( np.sin(X) + np.sin(3*Y) )
def do_plot(n, f, title):
#plt.clf()
plt.subplot(1, 3, n)
plt.pcolor(X, Y, f(data), cmap=cm, vmin=-4, vmax=4)
plt.title(title)
plt.colorbar()
plt.figure()
do_plot(1, lambda x:x, "all")
do_plot(2, lambda x:np.clip(x, -4, 0), "<0")
do_plot(3, lambda x:np.clip(x, 0, 4), ">0")
plt.show()
set colorbar range with contourf
contourf
indeed works a bit differently than other ScalarMappable
s. If you specify the number of levels (20 in this case) it will take them between the minimum and maximum data (approximately). If you want to have n
levels between two specific values vmin
and vmax
you would need to supply those to the contouring function
levels = np.linspace(vmin, vmax, n+1)
plt.contourf(fld,levels=levels,cmap='coolwarm')
Complete code:
import numpy as np
import matplotlib.pyplot as plt
fld=np.random.rand(10,10)
levels = np.linspace(0,2,21)
img=plt.contourf(fld,levels=levels,cmap='coolwarm')
plt.colorbar(img)
plt.show()
matplotlib colorbar limits for contourf
You could pass levels
parameter to matplotlib.pyplot.contourf
in order to specify the number and positions of the contour regions. Then you can set extend = 'both'
in order to draw the countour regions outside levels
range you used:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
CHI = np.linspace(-45, 45, 35);
M = np.linspace(0, 1, 35)
CHI, M = np.meshgrid(CHI, M)
R = 10*2*M*np.sin( 2 * np.deg2rad(CHI) )
levels = [-3, -2, -1, 0, 1, 2, 3]
cont = ax.contourf(CHI, M, R, levels = levels, extend = 'both')
ax.set_xlim(-45,45)
cbar = plt.colorbar(cont)
plt.show()
how to instantly update the colorbar range of a matplotlib from values of entries?
So what You want in the end is to change colormap vmin
and vmax
, when user change Min and Max input. You don't need to constantly update colormap, but just on change of those inputs.
You can do that by tracing input change with update callback.
Here is modified code which does colormap update when Min and Max input is changed:
from tkinter import *
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
root = Tk()
root.geometry("500x500")
Max, Min = IntVar(), IntVar()
label1 = Label(root, text="Min")
label1.place(x=10, y=35)
label2 = Label(root, text="Max")
label2.place(x=10, y=60)
vmin_entry = Entry(root, textvariable=Min, width=5)
vmin_entry.place(x=50, y=35)
vmax_entry = Entry(root, textvariable=Max, width=5)
vmax_entry.place(x=50, y=60)
# Define global variables
c, canvas = None, None
def plot():
global x, y, c, canvas
x, y = np.mgrid[slice(0, 100), slice(0, 100)]
z = (x * y)
figure = Figure(figsize=(4, 4))
ax = figure.add_subplot(111)
c = ax.pcolormesh(x, y, z, cmap='YlGn')
ax.figure.colorbar(c)
canvas = FigureCanvasTkAgg(figure, root)
canvas.get_tk_widget().place(x=0, y=80)
canvas.draw()
def update_colormap(*args, **kwargs):
global c, canvas
if c is not None:
try:
# Get vmin and vmax
vmin, vmax = int(vmin_entry.get()), int(vmax_entry.get())
except ValueError:
# Could not convert values to int, non integer value
return
if vmin > vmax:
return
# Set new limits
c.set_clim(vmin, vmax)
# Update plot
canvas.flush_events()
canvas.draw()
# Trace change of Min and Max and call update_colormap as a callabck
Min.trace("w", update_colormap)
Max.trace("w", update_colormap)
button1 = Button(root, text="Plot", command=plot)
button1.place(x=30, y=0)
root.mainloop()
Setting matplotlib colorbar range (larger range than the values plotted)
I finally managed to solve it.
Instead of vmin
and vmax
, I must pass a keyword to control the levels to draw, like this:
import matplotlib.pyplot as plt
import numpy as np
rd = np.random.rand(40,100)
surface = 18 * rd # maximum value will be 18
fig = plt.figure()
ax = fig.add_subplot(111)
cores = ax.contourf(surface[:], levels=range(41))
cbar = plt.colorbar(cores)
plt.show()
And I get the image I wanted:
Setting matplotlib colorbar range
Arg. It's always the last thing you try:
quadmesh.set_clim(vmin=0, vmax=15)
works.
Set Colorbar range with contourf in matplotlib
The following always produces a bar with colours that correspond to the colours in the graph, but shows no colours for values outside of the [vmin,vmax]
range.
It can be edited (see inline comment) to give you exactly the result you want, but that the colours of the bar then still correspond to the colours in the graph, is only due to the specific colour map that's used (I think):
# Start copied from your attempt
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(20)
y = np.arange(20)
data = x[:, None] + y[None, :]
X, Y = np.meshgrid(x, y)
vmin = 0
vmax = 15
fig, ax = plt.subplots()
# Start of solution
from matplotlib.cm import ScalarMappable
levels = 400
level_boundaries = np.linspace(vmin, vmax, levels + 1)
quadcontourset = ax.contourf(
X, Y, data,
level_boundaries, # change this to `levels` to get the result that you want
vmin=vmin, vmax=vmax
)
fig.colorbar(
ScalarMappable(norm=quadcontourset.norm, cmap=quadcontourset.cmap),
ticks=range(vmin, vmax+5, 5),
boundaries=level_boundaries,
values=(level_boundaries[:-1] + level_boundaries[1:]) / 2,
)
Always correct solution that can't handle values outside [vmin,vmax]
:
Requested solution:
Related Topics
Comparing Digits in an Integer in Python
How to Delete a Record by Id in Flask-Sqlalchemy
Add Excel File Attachment When Sending Python Email
Which Is Faster and Why Set or List
Remove the Selected Elements from the Image in Opencv
Create New Column Based on String
Counting How Many Times Each Vowel Appears
Best Practice to Run Multiple Spark Instance At a Time in Same Jvm
Import a File from a Subdirectory
Spark Add New Column With Value Form Previous Some Columns
Index Out of Bounds Error:Python
Convert Timedelta to Floating-Point
Python SQL Select With Possible Null Values
How to Calculate a Gaussian Kernel Matrix Efficiently in Numpy