0

With these lines, currently I'm having this kind of figure.

fig, ax = plt.subplots()
X, Y = np.meshgrid(x, y)
cs = ax.contourf(X, Y, Z, 50, cmap=cm.get_cmap('jet')) # linear mapping
#cs = ax.contourf(X, Y, Z, 50, locator=ticker.LogLocator(), cmap=cm.get_cmap('jet')) # log mapping
cbar = fig.colorbar(cs)
plt.show()

enter image description here

Now I want to plot this in Log scale, so if I activate the commented line, I get this kind of result which seems to ignore 'levels' argument which is set to '50'.

enter image description here

I've reached this post (Python matplotlib contour plot logarithmic color scale), but I am pretty sure that there is a way in which I do not have to set all the values of levels manually.

Does anyone has a comment, or any other handy python functions for logarithmatic contour plot with many levels?

Sangjun Lee
  • 406
  • 2
  • 12

1 Answers1

2

Setting the number of levels as a integer doesn't work for logscale but you can easily set the values with np.logspace(np.log10(z.min()),np.log10(z.max()), 50). Matplotlib 3.3.3 seems to have some difficulties in correctly formatting the colorbar ticks in this case, so you need to manually adjust them a bit.

import matplotlib.pyplot as plt
from matplotlib import ticker, cm
import numpy as np

x = np.linspace(-3.0, 3.0, 100)
y = np.linspace(-2.0, 2.0, 100)
X, Y = np.meshgrid(x, y)

Z1 = np.exp(-(X)**2 - (Y)**2)
Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2)
z = Z1 + 50 * Z2

fig, ax = plt.subplots()

n_levels = 50
cs = ax.contourf(X, Y, z, 
                 np.logspace(np.log10(z.min()),np.log10(z.max()), n_levels), 
                 locator=ticker.LogLocator(), 
                 cmap=cm.jet
                 )

cbar = fig.colorbar(cs)
cbar.locator = ticker.LogLocator(10)
cbar.set_ticks(cbar.locator.tick_values(z.min(), z.max()))
cbar.minorticks_off()

enter image description here

Stef
  • 28,728
  • 2
  • 24
  • 52
  • this only works for matplotlib < 3.5.0, it's broken in versions 3.5.0 - at least 3.5.3. – Stef Aug 18 '22 at 11:38