I am generating a heatmap based on array T. However, there is one value (1e-9) which is much lower than the rest (ignoring NaN). How do I adjust the colorbar so that I can see the minor changes in the remaining values of the array and also including 1e-9?
import numpy as np
from numpy import NaN
import matplotlib
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.pyplot as plt
T=np.array([[6.19314835e+02, 6.19229656e+02, 6.19220233e+02],
[6.14626547e+02, 6.18217141e+02, 6.19029892e+02],
[1.00000000e-09, NaN, NaN]])
fig, ax = plt.subplots()
im = ax.imshow(T)
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
You can use vmin and vmax to set a range for the color map. The extreme low values can be indicated via a 'lower' color in the color map together with extend='min' in the colorbar.
import numpy as np
import matplotlib.pyplot as plt
T = np.array([[6.19314835e+02, 6.19229656e+02, 6.19220233e+02],
[6.14626547e+02, 6.18217141e+02, 6.19029892e+02],
[1.00000000e-09, np.NaN, np.NaN]])
cmap = plt.get_cmap('viridis').copy()
cmap.set_under('red')
vmin = np.nanmin(T[T>1e-8])
vmax = np.nanmax(T)
fig, ax = plt.subplots()
im = ax.imshow(T, cmap=cmap, vmin=vmin, vmax=vmax)
plt.colorbar(im, ax=ax,extend='min')
plt.tight_layout()
plt.show()
Related
I am trying to align the matplotlib plot with its colorbar. However, when there is a tick on the top of the colormap, the figure itself shrinks a little bit:
Is there a way to equalize this distance (blue arrows) consistently?
For generating the plot, I am using following code:
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
ax.plot(...)
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes('right', '5%', pad='3%')
sm = plt.cm.ScalarMappable(cmap=plt.get_cmap('viridis'),
norm=mpl.colors.Normalize(vmin=0, vmax=60))
sm.set_array([])
fig.colorbar(sm, cax=cax)
plt.tight_layout()
plt.savefig('pic.png', dpi=500)
I am plotting a heatmap using the array T which carries the same element. But the colorbar seems to show a range of values. How can I adjust it so that it shows only one value i.e. 0.01109?
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.pyplot as plt
T=np.array([[0.01109, 0.01109, 0.01109],
[0.01109, 0.01109, 0.01109],
[0.01109, 0.01109, 0.01109]])
fig, ax = plt.subplots()
im = ax.imshow(T)
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
ax.set_title('\u03C3' ' ' "(N/m)")
I'm making some interactive plots and I would like to add a colorbar legend. I don't want the colorbar to be in its own axes, so I want to add it to the existing axes. I'm having difficulties doing this, as most of the example code I have found creates a new axes for the colorbar.
I have tried the following code using matplotlib.colorbar.ColorbarBase, which adds a colorbar to an existing axes, but it gives me strange results and I can't figure out how to specify attributes of the colorbar (for instance, where on the axes it is placed and what size it is)
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.cm import coolwarm
import numpy as np
x = np.random.uniform(1, 10, 10)
y = np.random.uniform(1, 10, 10)
v = np.random.uniform(1, 10, 10)
fig, ax = plt.subplots()
s = ax.scatter(x, y, c=v, cmap=coolwarm)
matplotlib.colorbar.ColorbarBase(ax=ax, cmap=coolwarm, values=sorted(v),
orientation="horizontal")
Using fig.colorbar instead ofmatplotlib.colorbar.ColorbarBase still doesn't give me quite what I want, and I still don't know how to adjust the attributes of the colorbar.
fig.colorbar(s, ax=ax, cax=ax)
Let's say I want to have the colorbar in the top left corner, stretching about halfway across the top of the plot. How would I go about doing that?
Am I better off writing a custom function for this, maybe using LineCollection?
This technique is usually used for multiple axis in a figure. In this context it is often required to have a colorbar that corresponds in size with the result from imshow. This can be achieved easily with the axes grid tool kit:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
data = np.arange(100, 0, -1).reshape(10, 10)
fig, ax = plt.subplots()
divider = make_axes_locatable(ax)
cax = divider.append_axes('right', size='5%', pad=0.05)
im = ax.imshow(data, cmap='bone')
fig.colorbar(im, cax=cax, orientation='vertical')
plt.show()
The colorbar has to have its own axes. However, you can create an axes that overlaps with the previous one. Then use the cax kwarg to tell fig.colorbar to use the new axes.
For example:
import numpy as np
import matplotlib.pyplot as plt
data = np.arange(100, 0, -1).reshape(10, 10)
fig, ax = plt.subplots()
cax = fig.add_axes([0.27, 0.8, 0.5, 0.05])
im = ax.imshow(data, cmap='gist_earth')
fig.colorbar(im, cax=cax, orientation='horizontal')
plt.show()
Couldn't add this as a comment, but in case anyone is interested in using the accepted answer with subplots, the divider should be formed on specific axes object (rather than on the numpy.ndarray returned from plt.subplots)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
data = np.arange(100, 0, -1).reshape(10, 10)
fig, ax = plt.subplots(ncols=2, nrows=2)
for row in ax:
for col in row:
im = col.imshow(data, cmap='bone')
divider = make_axes_locatable(col)
cax = divider.append_axes('right', size='5%', pad=0.05)
fig.colorbar(im, cax=cax, orientation='vertical')
plt.show()
I would like to display a 2D np.array with imshow and the respective colorbar which should share its axis with a histogram of the np.array. Here is an attempt, however, without shared axes.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots(figsize=(7,10))
data = np.random.normal(0, 0.2, size=(100,100))
cax = ax.imshow(data, interpolation='nearest', cmap=cm.jet)
divider = make_axes_locatable(plt.gca())
axBar = divider.append_axes("bottom", '5%', pad='7%')
axHist = divider.append_axes("bottom", '30%', pad='7%')
cbar = plt.colorbar(cax, cax=axBar, orientation='horizontal')
axHist.hist(np.ndarray.flatten(data), bins=50)
plt.show()
I tried to use the sharex argument in axHist with axHist = divider.append_axes("bottom", '30%', pad='7%', sharex=axBar) but this somehow shifts the histogram data:
Besides the shared axis x, how could one modify the histogram to take the same colors as the colormap, similar to here?
You may color every patch of histogram by bin value without sharex:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.colors import Normalize
fig, ax = plt.subplots(figsize=(7,10))
data = np.random.normal(0, 0.2, size=(100,100))
cax = ax.imshow(data, interpolation='nearest', cmap=cm.jet)
divider = make_axes_locatable(plt.gca())
axBar = divider.append_axes("bottom", '5%', pad='7%')
axHist = divider.append_axes("bottom", '30%', pad='7%')
cbar = plt.colorbar(cax, cax=axBar, orientation='horizontal')
# get hist data
N, bins, patches = axHist.hist(np.ndarray.flatten(data), bins=50)
norm = Normalize(bins.min(), bins.max())
# set a color for every bar (patch) according
# to bin value from normalized min-max interval
for bin, patch in zip(bins, patches):
color = cm.jet(norm(bin))
patch.set_facecolor(color)
plt.show()
For more information look for manual page: https://matplotlib.org/xkcd/examples/pylab_examples/hist_colormapped.html
Consider this example
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
plt.subplot(121)
img = plt.imshow([np.arange(0,1,.1)],aspect="auto")
ax = plt.gca()
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="3%", pad=0.5)
plt.colorbar(img, cax=cax, orientation='horizontal')
plt.subplot(122)
plt.plot(range(2))
plt.show()
I want to make these two figures (plot region without colorbar) of the same size.
The size is automatically adjusted if the colorbar is plotted vertically or if two rows are used (211, 212) instead of two columns.
One can basically do the same for the second subplot as for the first, i.e. create a divider and append an axes with identical parameters, just that in this case, we don't want a colorbar in the axes, but instead simply turn the axis off.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
ax = plt.subplot(121)
img = ax.imshow([np.arange(0,1,.1)],aspect="auto")
divider = make_axes_locatable(ax)
cax = divider.append_axes("bottom", size="3%", pad=0.5)
plt.colorbar(img, cax=cax, orientation='horizontal')
ax2 = plt.subplot(122)
ax2.plot(range(2))
divider2 = make_axes_locatable(ax2)
cax2 = divider2.append_axes("bottom", size="3%", pad=0.5)
cax2.axis('off')
plt.show()
You can now do this without recourse to an extra toolkit by using constrained_layout:
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 2, constrained_layout=True)
ax = axs[0]
img = ax.imshow([np.arange(0,1,.1)],aspect="auto")
fig.colorbar(img, ax=ax, orientation='horizontal')
axs[1].plot(range(2))
plt.show()