Skip to content

Instantly share code, notes, and snippets.

@matthewfeickert
Last active February 18, 2022 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewfeickert/93395d74724ef19d0c4670940868b52a to your computer and use it in GitHub Desktop.
Save matthewfeickert/93395d74724ef19d0c4670940868b52a to your computer and use it in GitHub Desktop.
Example for mplhep problem with contourf

mplhep styles with contourf log scale causes hang

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.

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.

Do you have any idea why this could be happening, and if there is a way to avoid it or fix it?

import matplotlib.colors as colors
import mplhep
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import rc_context
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)
# c.f. https://github.com/scikit-hep/mplhep/issues/362
rc_options = {"ytick.minor.visible": False} # yticks
with rc_context(rc_options):
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}")
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}")
mplhep==0.3.21
matplotlib==3.5.1
scipy==1.8.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment