mplhep styles with contourf log scale causes hang
See original GitHub issue(Available as a GitHub Gist here)
I’m trying to do an interpolation of some points on a grid with mplhep v0.3.21 for an analysis at the moment. However, if I try to use matplotlib.pyplot.contourf with log spaces color levels using mplhep will cause a warning along the lines of
# Locator attempting to generate 18497 ticks ([0.15405694150420948, ..., 999.9912470033628]), which exceeds Locator.MAXTICKS (1000).
and it will then hang (I don’t know if it resolves, as I kill it with a KeyboardInterrupt when it is clear it won’t finish in a second or so).
If I comment out the use of plt.style.use(mplhep.style.ATLAS) (this happens with mplhep.style.ROOT too) then things proceed as normal and produce the plot in example.py.
example.py:
import matplotlib.colors as colors
import mplhep
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import ticker
from matplotlib.ticker import LogFormatterSciNotation
from numpy import random
from numpy.random import PCG64, SeedSequence
from scipy.interpolate import LinearNDInterpolator
# generate observed values (x, y)
x_step = 250
x_range = np.arange(750, 3000 + x_step, step=x_step)
y_step = 150
y_range = np.arange(700, 2000 + y_step, step=y_step)
bit_generator = PCG64(SeedSequence(0))
rng = random.default_rng(bit_generator)
x = []
y = []
for step in x_range:
choose_n = rng.integers(low=0, high=y_range.size - 2)
for value in y_range[: choose_n + 2]:
x.append(step)
y.append(value)
x = np.asarray(x)
y = np.asarray(y)
# Generate uniform data on the interval [1e-3, 100.]
# Uniform [a,b) = (b - a) * random_sample() + a
uniform_range = [1e-3, 100.0]
z = (uniform_range[1] - uniform_range[0]) * rng.random(x.size) + uniform_range[0]
# Generate a 2D grid
x_coords = np.linspace(min(x), max(x), 100)
y_coords = np.linspace(min(y), max(y), 100)
x_grid, y_grid = np.meshgrid(x_coords, y_coords) # 2D grid for interpolation
# Interpolate with function of choice across the grid
# between the known values
interp_func = LinearNDInterpolator(list(zip(x, y)), z)
interp_Z = interp_func(x_grid, y_grid)
# plt.style.use(mplhep.style.ATLAS) # Uncommenting causes hang
# Locator attempting to generate 18497 ticks ([0.15405694150420948, ..., 999.9912470033628]), which exceeds Locator.MAXTICKS (1000).
fig, ax = plt.subplots()
# plot interpolated values
real_valued_Z = interp_Z[~np.isnan(interp_Z)]
step_exp = 0.25
levels_exp = np.arange(
np.floor(np.log10(real_valued_Z.min()) - 1),
np.ceil(np.log10(real_valued_Z.max()) + 1) + step_exp,
step=step_exp,
)
levels = np.power(10, levels_exp)
cs = ax.contourf(
x_grid,
y_grid,
interp_Z,
cmap="PuBu_r",
levels=levels,
norm=colors.LogNorm(vmin=levels.min(), vmax=levels.max()),
)
formatter = LogFormatterSciNotation(10, labelOnlyBase=False)
cbar = fig.colorbar(cs, format=formatter)
# plot observed values
scatter_size = 15.0
ax.scatter(x, y, s=scatter_size, color="white", edgecolors="black")
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$")
cbar.set_label(r"$z(x, y)$")
file_types = ["png", "pdf"]
for extension in file_types:
fig.savefig(f"example.{extension}")

What is interesting, is if I attempt to get around this by using pcolormesh and then contour to create a similar-ish type of plot there is no issue and things work as expected as can be seen in example_pmesh.py.
example_pmesh.py:
import matplotlib.colors as colors
import mplhep
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import ticker
from matplotlib.ticker import LogFormatterSciNotation
from numpy import random
from numpy.random import PCG64, SeedSequence
from scipy.interpolate import LinearNDInterpolator
# generate observed values (x, y)
x_step = 250
x_range = np.arange(750, 3000 + x_step, step=x_step)
y_step = 150
y_range = np.arange(700, 2000 + y_step, step=y_step)
bit_generator = PCG64(SeedSequence(0))
rng = random.default_rng(bit_generator)
x = []
y = []
for step in x_range:
choose_n = rng.integers(low=0, high=y_range.size - 2)
for value in y_range[: choose_n + 2]:
x.append(step)
y.append(value)
x = np.asarray(x)
y = np.asarray(y)
# Generate uniform data on the interval [1e-3, 100.]
# Uniform [a,b) = (b - a) * random_sample() + a
uniform_range = [1e-3, 100.0]
z = (uniform_range[1] - uniform_range[0]) * rng.random(x.size) + uniform_range[0]
# Generate a 2D grid
x_coords = np.linspace(min(x), max(x), 100)
y_coords = np.linspace(min(y), max(y), 100)
x_grid, y_grid = np.meshgrid(x_coords, y_coords) # 2D grid for interpolation
# Interpolate with function of choice across the grid
# between the known values
interp_func = LinearNDInterpolator(list(zip(x, y)), z)
interp_Z = interp_func(x_grid, y_grid)
plt.style.use(mplhep.style.ATLAS) # Here there is no problem
fig, ax = plt.subplots()
# plot interpolated values
real_valued_Z = interp_Z[~np.isnan(interp_Z)]
step_exp = 0.25
levels_exp = np.arange(
np.floor(np.log10(real_valued_Z.min()) - 1),
np.ceil(np.log10(real_valued_Z.max()) + 1) + step_exp,
step=step_exp,
)
levels = np.power(10, levels_exp)
pcm = ax.pcolormesh(
x_grid,
y_grid,
interp_Z,
cmap="PuBu_r",
norm=colors.LogNorm(vmin=levels.min(), vmax=levels.max()),
shading="auto",
)
formatter = LogFormatterSciNotation(10, labelOnlyBase=False)
cbar = fig.colorbar(pcm, format=formatter)
cs = ax.contour(
x_grid,
y_grid,
interp_Z,
cmap="PuBu_r",
)
# plot observed values
scatter_size = 15.0
ax.scatter(x, y, s=scatter_size, color="white", edgecolors="black")
ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$y$")
cbar.set_label(r"$z(x, y)$")
file_types = ["png", "pdf"]
for extension in file_types:
fig.savefig(f"example_pmesh.{extension}")

@andrzejnovak Do you have any idea why this could be happening, and if there is a way to avoid it or fix it?
cc @kratsg
Issue Analytics
- State:
- Created 2 years ago
- Comments:8 (8 by maintainers)

Top Related StackOverflow Question
Thanks @matthewfeickert
So @tacaswell was indeed right (from the IRIS-HEP Slack chats)
as going following the instructions in https://github.com/matplotlib/matplotlib/issues/9994#issuecomment-808985409 on how to find the nightly
matplotlibwheels that GHA builds, which I’ll recap here:matplotlib’s GitHub and select the latest PR build.branch:main is:successand select the top onecurlas there is no stable URL that you can consistently hit with this method):With this preview of the next
matplotlibrelease my example file with themplhepdefaults (the minimal edits to get that back are to use)
then things work fine. 👍
edit:
matplotlibnow has nightly wheels, so to get them just do