I have an application where I want to change the colors used to map a plot with (x,y,z) points dynamically. I created the following to demonstrate the basic idea.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
import tkinter as tk
from matplotlib.backends.backend_tkagg
import FigureCanvasTkAgg
class colorbar_app(tk.Tk):
def __init__(self):
super().__init__()
# create FigureCanvasTkAgg object containing a plot
self.fig, self.axes = plt.subplots(1,1,figsize=(8,6),
layout='constrained')
self.axes.plot(np.random.randn(1000), 'bo')
self.fig_canvas = FigureCanvasTkAgg(self.fig, self)
self.fig_canvas.draw()
# # Create stand-alone color bar figure plot
self.fig2, self.cbar_ax = plt.subplots(figsize=(8,0.75),
layout='constrained')
# Colorbar in a separate canvas
self.cmap = mpl.cm.rainbow
self.vmin, self.vmax = (0,10)
self.norm = mpl.colors.Normalize(vmin=self.vmin, vmax=self.vmax)
# Insert the colorbar into the colorbar figure
xx = mpl.cm.ScalarMappable(norm=self.norm, cmap=self.cmap)
self.cbar = self.fig2.colorbar(xx, cax=self.cbar_ax,
orientation='horizontal',
label = 'XXXX')
self.cbar_canvas = FigureCanvasTkAgg(self.fig2, self)
self.custom_toolbar() # create a custom toolbar
self.fig_canvas.get_tk_widget().pack()
self.cbar_canvas.get_tk_widget().pack()
self.toolbar.pack(side=tk.LEFT)
def custom_toolbar(self):
self.toolbar = tk.Frame(self.master, bd=1, relief=tk.RAISED)
self.colorbyLabel = tk.Label(self.toolbar, text='ColorBy: ')
self.moreButton = tk.Button(self.toolbar, text='MORE', bg='light green',
command=self.on_more_button)
self.colorbyLabel.pack(side=tk.LEFT, padx=2, pady=2)
self.moreButton.pack(side=tk.LEFT, padx=2, pady=2)
def on_more_button(self):
print('MORE button pressed')
self.vmin, self.vmax = self.vmin*2, self.vmax*2
self.norm = mpl.colors.Normalize(vmin=self.vmin, vmax=self.vmax)
xx = mpl.cm.ScalarMappable(norm=self.norm, cmap=self.cmap)
self.cbar = self.fig2.colorbar(xx, cax=self.cbar_ax,
orientation='horizontal',
label = 'MORE')
self.cbar.set_ticks(np.linspace(self.vmin, self.vmax, 100))
app = colorbar_app()
app.mainloop()
This creates the general idea – a plot window with a colorbar below and a toolbar with buttons below that. I used a simple plot rather than the LineCollections I actually plot. These can be colorized, the plot I have here … not so much.
When I press the button, I want to change the colormap range used to (eventually) replot the data on the top but I can’t figure out how to get the colorbar to display the new range, or a new label. Didn’t find anything on-line on how to do this, but I did write an app 10 years ago that did accomplish this. Can’t recall how I did it before. Any suggestions?
I tried cbar.set_ticks(), tried to change clims .. but just can’t find the right combination.
Chris Michalski is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
Of course, once I posted I finally figured it out. What was missing was a call to the canvas to redraw the colorbar. I added this line to the end of on_more_button():
self.cbar_canvas.draw()
And now the colorbar updates whenever the MORE button is pressed.
Chris Michalski is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.