Получить истинный предел площади участка Оси в matplotlib? - PullRequest
0 голосов
/ 24 июня 2018

Я хотел бы узнать точные экстенты данных внутри объекта 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()?)

...