Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reset default matplotlib colormap values after using 'set_under' or 'set_over'

This is something that has been bugging me for a while. Whenever I use the cmap.set_under() or cmap.set_over() methods to change the the color of out of bound values, they seem to apply these changes to ALL instances where I use that colormap. Below is an example of what I am referring to.

import matplotlib.pyplot as plt 
import numpy as np

rand_data = np.random.randint(50, size=(20,20))

plt.figure()
plt.subplot(211)
cmap1 = plt.cm.rainbow
im1 = plt.pcolormesh(rand_data, cmap=cmap1, vmin=10)
im1.cmap.set_under('w')
plt.colorbar(extend='min')

plt.subplot(212)
cmap2 = plt.cm.rainbow
im2 = plt.pcolormesh(rand_data, cmap=cmap2, vmin=10)
im2.cmap.set_under('k')
plt.colorbar(extend='min')

plt.show()

Here I am trying to create two plots of the same values. In the first plot, I want all values below 10 to be white. In the second plot, I want all values below 10 to be black. The result is this:

It appears that the second time I used set_under it reset the set_under for all existing plots that use the rainbow colormap. If I use a different colormap in the second plot, I able to set a different set_under color:

enter image description here

Even more bizarre, if use cmap.set_under() or cmap.set_over() in a function or script, this setting does not reset after exiting that function. That is, if I comment out the lines where I explicitly defined the set_under and colors re-run my script, I get the same result as before.

So I have a couple questions:

  1. Is there a way to set the color of out-of-bounds values of a colormap for a single plot without affecting the colormap of any existing plots?

  2. How do I reset the out-of-bounds values to their original colors?

For the second question, I know I can manually add back in the original colors by doing something like this:

N = cmap.N
cmap.set_under(cmap(1))
cmap.set_over(cmap(N-1))

But, I feel like there should be an easier way.

like image 782
nikobam Avatar asked Mar 16 '17 19:03

nikobam


1 Answers

The behaviour you describe is expected. There is only a single colormap present, which is plt.cm.rainbow. When you first set_under('w') and later set_under('k'), the color for under will be black.

What you want to do is actually use two different instances of the same colormap and then change each instance to have a different value for the lower bound.
This can easily be done using copy,

cmap1 = copy.copy(plt.cm.rainbow)

Now manipulating cmap1 does not change the rainbow colormap itself, such that it is possible to later create another copy of it and apply different settings.

import matplotlib.pyplot as plt 
import numpy as np
import copy

rand_data = np.random.randint(50, size=(20,20))

plt.figure()
plt.subplot(211)
cmap1 = copy.copy(plt.cm.rainbow)
im1 = plt.pcolormesh(rand_data, cmap=cmap1, vmin=10)
im1.cmap.set_under('w')
plt.colorbar(extend='min')

plt.subplot(212)
cmap2 = copy.copy(plt.cm.rainbow)
im2 = plt.pcolormesh(rand_data, cmap=cmap2, vmin=10)
im2.cmap.set_under('k')
plt.colorbar(extend='min')

plt.show()

enter image description here

like image 182
ImportanceOfBeingErnest Avatar answered Nov 03 '22 03:11

ImportanceOfBeingErnest