Установите автоматическое ограничение на график, чтобы иметь буфер вокруг всех точек - PullRequest
10 голосов
/ 24 мая 2011

Я хотел бы построить набор точек, используя pyplot в matplotlib, но ни одна из точек не должна находиться на краю моей оси.Автомасштаб (или что-то) устанавливает xlim и ylim таким образом, что часто первая и последняя точки лежат на x = xmin или xmax, что затрудняет чтение в некоторых ситуациях.

Это большечасто проблематично с графиками loglog() или semilog(), потому что для автомасштабирования нужно, чтобы xmin и xmax были точными степенями десяти, но если мои данные содержат только три точки, например, на xdata = [10**2,10**3,10**4], то первая и последняя точкибудет лежать на границе графика.

Попытка обойти

Это мое решение, чтобы добавить 10% -ый буфер к любой стороне графика.Но есть ли способ сделать это более элегантно или автоматически?

from numpy import array, log10
from matplotlib.pyplot import *

xdata = array([10**2,10**3,10**4])
ydata = xdata**2

figure()
loglog(xdata,ydata,'.')
xmin,xmax = xlim()
xbuff = 0.1*log10(xmax/xmin)
xlim(xmin*10**(-xbuff),xmax*10**(xbuff))

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

Линейный график

Чтобы пояснить, что я делаю в своем обходном пути, я должен добавить пример в линейном пространстве (вместо пространства журнала):

plot(xdata,ydata)
xmin,xmax = xlim()
xbuff = 0.1*(xmax-xmin)
xlim(xmin-xbuff,xmax+xbuff))

, который идентиченк предыдущему примеру, но для линейной оси.

Пределы слишком велики

Связанная проблема заключается в том, что иногда пределы слишком велики.Скажем, мои данные похожи на ydata = xdata**0.25, так что дисперсия в диапазоне намного меньше, чем десятилетие, но заканчивается точно на 10**1.Затем автомасштабирование ylim составляет от 10**0 до 10**1, хотя данные находятся только в верхней части графика.Используя мой обходной путь, описанный выше, я могу увеличить ymax, чтобы третья точка полностью находилась в пределах, но я не знаю, как увеличить ymin, чтобы в нижней частимой сюжетто есть дело в том, что я не всегда хочу раздвигать свои пределы, а просто хотел бы иметь некоторый постоянный (или пропорциональный) буфер вокруг всех моих точек.

Ответы [ 2 ]

8 голосов
/ 21 сентября 2015

@ askewchan Я только что успешно добился того, как изменить настройки matplotlib, отредактировав файл конфигурации matplotlibrc и запустив python прямо из терминала. Пока не знаю причину, но matplotlibrc не работает, когда я запускаю python из spyder3 (моя IDE). Просто следуйте инструкциям здесь matplotlib.org / users / customizing.html .

1) Решение одно (по умолчанию для всех графиков)

Попробуйте поместить это в matplotlibrc, и вы увидите увеличение буфера:

axes.xmargin        : 0.1  # x margin.  See `axes.Axes.margins`
axes.ymargin        : 0.1  # y margin See `axes.Axes.margins`

Значения должны быть в диапазоне от 0 до 1.

Obs.: Из-за ошибок весы работают некорректно.Это будет исправлено для matplotlib 1.5 (у меня пока 1.4.3 ...).Дополнительная информация:

2) Решение второе (индивидуально для каждого графика внутри кода)

Существует также функция полей (для непосредственного ввода вкод).Пример:

import numpy as np
from matplotlib import pyplot as plt 
t = np.linspace(-6,6,1000)
plt.plot(t,np.sin(t))
plt.margins(x=0.1, y=0.1)
plt.savefig('plot.png')

Obs.: Здесь работает масштаб (0,1 увеличит 10% буфера до и после x-диапазона и y-диапазона).

3 голосов
/ 25 мая 2011

A аналогичный вопрос был задан в списке пользователей matplotlib ранее в этом году.Наиболее многообещающее решение включает реализацию локатора (в данном случае основанного на MaxNLocator ) для переопределения MaxNLocator.view_limits.

...