[Python] How can I change a Matplotlib colormap dynamically and get its range and labels...

Discussão em 'Python' iniciado por Stack, Setembro 25, 2024.

  1. Stack

    Stack Membro Participativo

    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.

    Continue reading...

Compartilhe esta Página