Janosh
Janosh

Reputation: 4732

Show exponentiated values along opposite side of log color scale

With a horizontal log-scaled color bar and logged labels along the bottom, is it possible to show the exponentiated (original) values along the top?

So in this example, there should be ticks and labels along the top of the color bar going from mat.min() = 0.058 to mat.max() = 13.396

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

mat = np.exp(np.random.randn(20, 20))

plt.matshow(mat)

norm = mpl.colors.Normalize(1, np.log(mat.max()))
plt.colorbar(plt.cm.ScalarMappable(norm=norm), orientation="horizontal")

plt.savefig("rand_mat.png", dpi=200)

random matrix

Upvotes: 1

Views: 67

Answers (2)

Janosh
Janosh

Reputation: 4732

At the risk of committing a faux pas, I'll answer my own question with the solution that best suits my needs:

cb.ax.secondary_xaxis("top", functions=(np.exp, np.log))

which gives

random matrix

Full Code

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

mat = np.exp(np.random.randn(20, 20))

plt.matshow(mat)

norm = mpl.colors.Normalize(np.log(mat.min()), np.log(mat.max()))
cb = plt.colorbar(plt.cm.ScalarMappable(norm=norm), orientation="horizontal")

cb_ax_top = cb.ax.secondary_xaxis("top", functions=(np.exp, np.log))
cb_ax_top.set_xticks([0.1, 0.5, 1, 4, 10, 20])

Upvotes: 1

r-beginners
r-beginners

Reputation: 35205

Here is the best answer for your response. I've customized it based on that. Does this result match the intent of your question? The color bar and the size of the figure are not the same, so I adjusted them.

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

np.random.seed(20210404)
mat = np.exp(np.random.randn(20, 20))

norm = mpl.colors.Normalize(1, np.log(mat.max()))

fig, (ax, cax) = plt.subplots(nrows=2, gridspec_kw=dict(height_ratios=[15,1],hspace=0.5))
im = ax.matshow(mat)
cbar = plt.colorbar(plt.cm.ScalarMappable(norm=norm), orientation="horizontal", cax=cax)
cax2 = cax.twiny()

cbar.ax.xaxis.set_label_position("bottom")
         
iticks = np.arange(mat.min(), mat.max(), 2)               
cax2.set_xticks(iticks)

ax_pos = ax.get_position()
cax_pos = cbar.ax.get_position()
new_size = [ax_pos.x0, cax_pos.y0, ax_pos.x1 - ax_pos.x0, cax_pos.y1 - cax_pos.y0]
cbar.ax.set_position(new_size) 

plt.show()

enter image description here

Upvotes: 2

Related Questions