2016-06-14 5 views
1

Мне нужно получить график x, y с логарифмической шкалой по осям x. Когда я увеличиваю оси x, вы должны автомасштабировать как (не логарифмические) оси y.Python matplotlib logarithmic autoscale

plt.xscale('log') 
plt.grid(True) 
plt.autoscale(True,True,True) 
plt.legend(loc='best') 
plt.show() 

Normal print

Zoomed in print

Как вы можете видеть, что не работает автомасштаба функция на х-оси. Как я могу отобразить это правильно?

ответ

0

Если вы посмотрите документацию функция как-

matplotlib.pyplot.autoscale(enable=True, axis='both', tight=None) 

Что вы отправляете это неверный аргумент ...

просто сделать его

plt.autoscale(True, axis = 'both') 

И о жесткой -

Если True, установите представление l соответствует лимитам данных; если False, то поля локатора и расширяют пределы представления; если нет, используйте плотное масштабирование, если только художник - это изображение, иначе относиться к нему как к ложному. Плохая настройка сохраняется для будущего автомасштаба, пока она не будет явно изменена.

+1

Спасибо. Я скорректировал код, подобный этому: «plt.xscale (« log ») plt.grid (True) plt.autoscale (True, axis = 'both') plt.legend (loc = 'best') plt. show() ', но это то же самое, что и раньше. Когда я удаляю 'plt.xscale ('log')', он работает правильно. – Florian

1

Решение @ hashcode55 не работает, поскольку это то, что я пытался, прежде чем нашел эту тему.

Мне кажется, что это просто «ошибка» в том, что:

plt.yscale('log') 
plt.autoscale(enable=True, axis='y') 

не совместимы.

Вот мой пример кода:

import matplotlib.pyplot as plt 
import matplotlib 
import random 
import numpy as np 

# generate some random data and add it to the plot 
x = np.array(range(1,100)) 
y = np.maximum(np.ones(99), np.random.randn(99)) 
plt.plot(x, y, markersize=4, marker='.', color='red') 

# format 
ax = plt.gca() 
plt.ylabel('LOGARITHMIC SCALE') 
plt.yscale('log') 
plt.minorticks_on 
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter()) 
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter()) 
plt.autoscale(enable=True, axis='y') 

#ax.set_ylim([np.min(y), np.max(y)]) 

#plot 
plt.show() 

, который производит:

enter image description here логарифмическая шкала

, но явно не AutoScale

если удалить комментарии из этой строки :

ax.set_ylim([np.min(y), np.max(y)]) 

Тогда на самом деле участки, как можно было бы ожидать с AutoScale:

enter image description here

Хороший, но что делать, если я потерял ссылку на мой у значений на графике?

В то время как это решение/ответ является хорошим «взломом» этой проблемы с образцом, это не является прочным решением для моей ситуации, так как мой график: a) live; постоянно обновляется каждую минуту; b) содержит МНОГИЕ участки; c) удаляет данные старше 24 часов; поэтому такое решение получило бы действительно хакерство, если бы оно было реализовано каждый раз, когда что-то добавлялось или удалялось из сюжета в реальном времени.

я был бы заинтересован в подлинном встроенного решения «AutoScale», если таковой существует, что работает с лог у шкалы, и я могу автоматическое обновление с помощью plt.ion()

до тех пор, что по этому поводу :

ч/т @David Z How to extract data from matplotlib plot

#if you do need to get data out of a plot, I think this should do it 

gca().get_lines()[n].get_xydata() 

#Alternatively you can get the x and y data sets separately: 

line = gca().get_lines()[n] 
xd = line.get_xdata() 
yd = line.get_ydata() 

реализованы в нашей ситуации под рукой (с дополнительной синей линии, чтобы проверить несколько строк), как:

import matplotlib.pyplot as plt 
import matplotlib 
import random 
import numpy as np 

# generate some random data and add it to the plot 
x = np.array(range(1,100)) 
y = np.maximum(np.ones(99), np.random.randn(99)) 
plt.plot(x, y, markersize=4, marker='.', color='red') 

# test for compatibility with multilpes lines 
x = np.array(range(1,100)) 
y = np.maximum(np.ones(99), 1.5*np.random.randn(99)) 
plt.plot(x, y, markersize=4, marker='.', color='blue') 

# format 
ax = plt.gca() 
plt.ylabel('LOGARITHMIC SCALE') 
plt.yscale('log') 
plt.minorticks_on 
ax.yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter()) 
ax.yaxis.set_minor_formatter(matplotlib.ticker.ScalarFormatter()) 
#plt.autoscale(enable=True, axis='y') 

##################################################### 
#force 'autoscale' 
##################################################### 
yd = [] #matrix of y values from all lines on plot 
for n in range(len(plt.gca().get_lines())): 
     line = plt.gca().get_lines()[n] 
     yd.append(line.get_ydata()) 
ax.set_ylim([0.9*np.min(yd), 1.1*np.max(yd)]) 
##################################################### 

#plot 
plt.show() 

который, по существу, тянет все данные y от всех линий на графике, нахождение максимума и мин; затем реализуя их через set_ylim; "Заставляя" AutoScale

выходы:

enter image description here

вуаля!

для моей ситуации я имел несколько более сложные сюжеты в формате:

plt.plot((x1,x2), (y1,y2)) 

создает матрицу в матричной ситуации производящего «Значения ошибки»

для этого мне пришлось придавить с помощью:

yd = [item for sublist in yd for item in sublist] 

ч/т @Alex Мартелли Making a flat list out of list of lists in Python

и это был конечный продукт:

##################################################### 
#force 'autoscale' 
##################################################### 
yd = [] #matrix of y values from all lines on plot 
for n in range(len(plt.gca().get_lines())): 
     line = plt.gca().get_lines()[n] 
     yd.append((line.get_ydata()).tolist()) 

yd = [item for sublist in yd for item in sublist] 
ax.set_ylim([0.9*np.min(yd), 1.1*np.max(yd)]) 
##################################################### 

enter image description here

Смежные вопросы