I am using pcolor
to generate the following plot (code below). It has a colorbar
in log scale and the x-values are in log-scale too. The problem is that the rectangles in this plot have different widths (I've put a red grid to show the rectangles better, suggestion of Trenton). Is there any way in which I can make sure the width of each rectangle is the same?
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np
# Generate Values
x_values = np.geomspace(start=1, stop=1e-2, num=6)
y_values = np.arange(start=0, stop=50, step=4, dtype=int)
x_grid, y_grid = np.meshgrid(x_values, y_values)
z_values = np.random.randn(len(y_values), len(x_values))
fig, ax = plt.subplots()
im = ax.pcolor(x_grid, y_grid, z_values, norm=matplotlib.colors.LogNorm(), ec='r', lw=2)
ax.set_xscale('log')
fig.colorbar(im)
plt.show()
You need to specify the bin edges. Probably a better way to do this in numpy
, but the idea is simple - transform to log space, get the bin edges by linear interpolation, and then transform back to normal space.
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np
# Generate Values
x_values = np.geomspace(start=1, stop=1e-2, num=6)
y_values = np.arange(start=0, stop=50, step=4, dtype=int)
# edges?
logx = np.log10(x_values)
edgex = np.hstack((
logx[:-1] - np.diff(logx) / 2,
logx[-1] - np.diff(logx)[-1] / 2, logx[-1] + np.diff(logx)[-1] / 2))
edgex = 10**edgex
edgey = np.hstack((
y_values[:-1] - np.diff(y_values) / 2,
y_values[-1] - np.diff(y_values)[-1] / 2, y_values[-1] + np.diff(y_values)[-1] / 2))
np.random.seed(12345)
z_values = np.random.randn(len(y_values), len(x_values))
fig, axs = plt.subplots(1, 2, layout='constrained')
ax = axs[0]
im = ax.pcolormesh(x_values, y_values, z_values, norm=LogNorm(), ec='r', lw=2)
ax.set_xscale('log')
ax.set_title('Linear gaps')
ax.plot(x_values, 0 * x_values, 'dm')
fig.colorbar(im)
ax = axs[1]
im = ax.pcolormesh(edgex, edgey, z_values, norm=LogNorm(), ec='r', lw=2)
ax.plot(x_values, 0 * x_values, 'dm')
ax.set_xscale('log')
ax.set_title('Log gaps')
fig.colorbar(im)