Почему контурные метки matplotlib заставляют контуры исчезать?

#python #matplotlib #contour

#python #matplotlib #контур

Вопрос:

Образец данных генерируется следующим образом,

 import matplotlib as mpl
print(mpl.__version__) # 3.3.3
import matplotlib.pyplot as plt
import numpy as np

def f(x, y=0):
    return np.piecewise(x, [x < 1, np.logical_and(1 <= x, x < 10), x >= 10], [lambda x: 0, lambda x: (x - 1) / 9 * 1000, lambda x: 1000])

x = np.logspace(-5, 5, 100)
y = np.logspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
 

Я пытаюсь построить график, используя следующий код, но некоторые контуры исчезают после вызова clabel .

 fig, ax = plt.subplots(figsize=(5, 3), dpi=120)
cr = ax.contour(X, Y, Z, levels=3, colors='black')
ax.clabel(cr, inline=True, fontsize=8, fmt='%d')
ax.set_xscale('log')
ax.set_yscale('log')
plt.show()
 

введите описание изображения здесь

Эта проблема все еще появляется, даже когда ширина линии контура и размер шрифта метки уменьшаются.

 fig, ax = plt.subplots(figsize=(5, 3), dpi=120)
cr = ax.contour(X, Y, Z, levels=3, colors='black', linewidths=0.6)
ax.clabel(cr, inline=True, fontsize=3, fmt='%d')
ax.set_xscale('log')
ax.set_yscale('log')
plt.show()
 

введите описание изображения здесь

Я не могу понять, как исправить странное поведение contour and clabel , и я подозреваю, что это связано с их несовместимостью с логарифмической шкалой.

Ответ №1:

Это действительно проблема логарифмических осей, особенно вокруг нулевой асимптоты. Однако почему бы не определить оси журнала перед построением графика, чтобы matplotlib мог учитывать это при построении графика?

 import matplotlib as mpl
print(mpl.__version__) # 3.3.3
import matplotlib.pyplot as plt
import numpy as np

def f(x, y=0):
    return np.piecewise(x, [x < 1, np.logical_and(1 <= x, x < 10), x >= 10], [lambda x: 0, lambda x: (x - 1) / 9 * 1000, lambda x: 1000])

x = np.logspace(-5, 5, 100)
y = np.logspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)

fig, ax = plt.subplots(figsize=(5, 3), dpi=120)
ax.set_xscale('log')
ax.set_yscale('log')
cr = ax.contour(X, Y, Z, levels=3, colors='black')
ax.clabel(cr, inline=True, fontsize=8, fmt='%d')

plt.show()
 

Пример вывода:
введите описание изображения здесь