1

I've a spatial field of values that I'm outputting on a regular interval over the course of a day. I'm plotting with contourf and I would like to do the following over the course of the day's data:

  • limit the colors on the colobar to values that represent the min and max of the day's data
  • hold the color bar static over 24 hourly plots at the max and min of the days data
  • hold the labels static over the course of those 24 hours

For example:

data = np.random.uniform(0, 5, size=(24,30,30))
data[3,:,:]=np.random.uniform(1,3,size=(30,30))  # example of bad plot
fgsize=(12,4)
numrecs = np.size(data,axis=0)
cbar_min = np.min(data)
cbar_max = np.max(data)
cbarlabels = np.linspace(np.floor(cbar_min), np.ceil(cbar_max), num=5, endpoint=True)


for tt in range(0, numrecs):
    plt.figure(figsize=fgsize, dpi=80)
    plt.title('this is a title')
    plt.contourf(data[tt, :, :], 35, vmin=cbar_min, vmax=cbar_max, cmap='coolwarm')
    cbar =plt.colorbar()
    cbar.set_ticks(cbarlabels)
    cbar.set_ticklabels(cbarlabels)
    cbar.set_label('my data has units')
    plt.show()
    plt.close()

Here is and example of a bad plot. The colors seem limited, but the color bar changes its color/label limits. How do I fix this?

Here is an example of a good plot.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
SBFRF
  • 167
  • 2
  • 16

1 Answers1

4

It turns out that contourf is a bit tricky in setting the levels for the colormap, see this answer. You can get the proper limits and colours by normalising the contours, as follows:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.uniform(0, 5, size=(24,30,30))
data[3,:,:]=np.random.uniform(1,3,size=(30,30))  # example of bad plot
fgsize=(12,4)
numrecs = np.size(data,axis=0)
cbar_min = np.min(data)
cbar_max = np.max(data)
cbarlabels = np.linspace(np.floor(cbar_min), np.ceil(cbar_max), num=5, endpoint=True)

# Set the normalisation for 35 levels (as in your example)
import matplotlib.colors as mc
levels = np.linspace(np.floor(cbar_min), np.ceil(cbar_max), 35) # to draw 35 levels
norm = mc.BoundaryNorm(levels, 256)

for tt in range(0, numrecs):
    print cbar_min, cbar_max
    plt.figure(figsize=fgsize, dpi=80)
    plt.title('this is a title')

    # Draw those levels, with proper normalisation, here:
    plt.contourf(data[tt, :, :], levels, vmin=cbar_min, vmax=cbar_max, cmap='coolwarm', levels=levels, norm=norm)

    cbar = plt.colorbar()
    cbar.set_ticks(cbarlabels)
    cbar.set_ticklabels(cbarlabels)
    cbar.set_label('my data has units')
    plt.show()
Community
  • 1
  • 1
lab
  • 860
  • 1
  • 9
  • 14
  • thanks lab, i got it fixed with your help. It was making weird numeral limits to the plot without having the cbar_min cbar_max rounded down/up accordingly. but it's fixed! many thansk – SBFRF Jan 27 '16 at 21:52
  • @SBFRF glad I could help! If you like the answer, would you mind accepting it? – lab Jan 27 '16 at 21:56