Я хотел бы узнать точные экстенты данных внутри объекта Axp matplotlib;т.е. их самые высокие и самые низкие значения х, а также самые высокие и самые низкие значения у.(Моему конкретному приложению требуется только, чтобы я мог определить наибольшее значение x с ошибкой менее 0,5, но мне любопытно, что касается общего случая.)
Вы должны использовать Axes.get_xlim()
и .get_ylim()
, чтобы получить экстент объекта Axes, но из-за полей эти пределы будут немного выходить за пределы данных.Например:
import matplotlib.pyplot as plt
plt.plot(range(100), range(100))
ax = plt.gca()
print(ax.get_xlim()) # prints (-4.95, 103.95)
Поля даны Axes.margins()
как часть осей, так что, если мы вычтем их?В итоге мы немного недооцениваем пределы:
xlim, xmargin = ax.get_xlim(), ax.margins()[0]
width = xlim[1] - xlim[0]
lower_xlim = xlim[0] + width*xmargin # 0.495, should be 0
upper_xlim = xlim[1] - width*xmargin # 98.505, should be 99
Методом проб и ошибок мы обнаруживаем, что, если мы умножим корректирующий член на 10/11
, мы наконец достигнем нашей отметки:
lower_xlim = xlim[0] + width*xmargin*10/11 # 0.
upper_xlim = xlim[1] - width*xmargin*10/11 # 99.
При ближайшем рассмотрении с различными диапазонами данных и размерами полей выясняется, что фактический коэффициент равен:
lower_xlim = xlim[0] + width*5/110 # 0.
upper_xlim = xlim[1] - width*5/110 # 99.
Очень странно, но работает очень хорошо.За исключением ... что если мы используем Axes.imshow()
вместо Axes.plot()
?График в этом случае не имеет полей (если Axes.use_sticky_edges()
равен True
, что является значением по умолчанию), но результат Axes.margins()
одинаков в любом случае.Кроме того, это может быть испорчено добавлением художников без данных, таких как текстовые поля, за пределами текущих границ.(Возможно. Я никогда не пробовал.)
Я знаю, что надежный способ найти пределы данных - это перебрать все данные в объекте Axes и вычислить их максимумы и минимумы.Это можно сделать, обнаружив артистов объекта Axes с помощью Axes.get_children()
и извлекая данные у тех, кто предоставляет метод .get_data()
.Но это очень дорого в вычислительном отношении.
Есть ли лучший способ?Или мой взлом 5/110 - лучшая вещь?Почему коэффициент 5/110 даже требуется?Почему это не зависит от xmargin
?(Должен ли я сначала позвонить Axes.autoscale()
?)