2

I am trying to put a scientific notation in all ticks of colorbar (the figure below). I could make it by colorbar(cs, format='%.2e'). The problem is that after I set tick labels using the following lines

cbar.set_ticks(levels)
cbar.set_ticklabels(levels)

the lower limit of notation seems to change to -5 and it shows normal digits for -4 like the figure below (note the tick label 0.00036). I know that one can change scientific notation limits for axes through ticklabel_format. I am looking for the same option for colorbar to change it from -5 to -4.

Any help is appreciated.

Update1:

I have used the following codes but no luck yet.

cbformat = matplotlib.ticker.ScalarFormatter()
cbformat.set_powerlimits((-12,12))
cbformat.set_scientific('%.2e')
cbar = m.colorbar(cs, location='right',format=cbformat, pad="10%")
cbar.set_ticks(levels)
cbar.set_ticklabels(np.round(levels,7))

Update 2:

To reproduce the problem, please use the following codes I copied from this post

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import ticker
from matplotlib.colors import LogNorm

z = np.random.lognormal(mean=10, sigma=3, size=(10,10))
z=z*10**-11
levels = np.linspace(z.min(), np.quantile(z,0.8), 8)
levels = np.append(levels, np.quantile(z,0.85))
levels = np.append(levels, np.quantile(z,0.9))
levels = np.append(levels, np.quantile(z,0.95))
levels = np.append(levels, z.max())   

fig, ax = plt.subplots()
# levels=np.logspace(np.log10(np.min(z)),np.log10(np.max(z)),100)
plot = ax.contourf(z, levels, norm=LogNorm())

cbar = fig.colorbar(plot, location='right',format='%.2e')
cbar.set_ticks(levels)
cbar.set_ticklabels(np.round(levels,9))

plt.show()

enter image description here

  • IIUC you could use [`set_powerlimits`](https://matplotlib.org/stable/api/ticker_api.html#matplotlib.ticker.ScalarFormatter.set_powerlimits) here – Rabinzel Sep 22 '22 at 05:15
  • @Rabinzel Thanks for your reply. I have tried the following, but no luck. cbformat = matplotlib.ticker.ScalarFormatter() cbformat.set_powerlimits((-12,12)) cbformat.set_scientific('%.2e') cbar = m.colorbar(cs, location='right',format=cbformat, pad="10%") cbar.set_ticks(levels) cbar.set_ticklabels(np.round(levels,7)) – Seyed Omid Nabavi Sep 22 '22 at 06:36
  • I think set_powerlimits only refers to the number after e and not the whole number. Instead of setting it to -12, try to set it to -5 – Rabinzel Sep 22 '22 at 07:27
  • @Rabinzel it also does not work – Seyed Omid Nabavi Sep 22 '22 at 07:54
  • 1
    Can you please add a sample of your data to reproduce the problem? – Rabinzel Sep 22 '22 at 08:00
  • @Rabinzel, I have added the sample code to my question. – Seyed Omid Nabavi Sep 22 '22 at 10:56
  • Try that [answer from unutbu](https://stackoverflow.com/a/25983372), with a brief adaption to `return r'${}e^{{{}}}$'.format(a, b)` on your provided example it seems to me that could be what you are looking for. Also you can easily adapt `{:.2e}` in ` a, b = '{:.2e}'.format(x).split('e')` to further change the displayed digits. – MagnusO_O Sep 22 '22 at 18:07

1 Answers1

1

you can specify the ticks when creating the colorbar, then the cbformat works. IIUC the following plot is what you want:

fig, ax = plt.subplots()
plot = ax.contourf(z, levels, norm=LogNorm())

cbformat = ticker.ScalarFormatter()
cbformat.set_scientific('%.2e')
cbformat.set_powerlimits((-4,12))
cbformat.set_useMathText(True)
cbar = fig.colorbar(plot, ticks=levels, location='right', format=cbformat)

plt.show()

enter image description here

Rabinzel
  • 7,757
  • 3
  • 10
  • 30