2017-01-14 3 views
-1

Я пытаюсь построить две линии с разными шкалами с matplotlib. В настоящее время работает, за исключением случаев, когда я запускаю свой код, вторая ось Y беспорядочна при обновлении.clear ax2 in matplotlib

Вот код, я использую:

import matplotlib.pyplot as plt 
import matplotlib.dates as mdates 
from matplotlib.pyplot import cm 
from datetime import datetime 
import numpy as np  
import matplotlib.animation as animation 

def animate(i, fig, ax): 
# Converter function 
    datefunc = lambda x: mdates.date2num(datetime.strptime(x, '%d-%m-%Y_%H:%M:%S')) 

    # Read data from 'file.dat' 
    dates, levels, temp = np.genfromtxt('datosPlot.txt', # Data to be read 
             converters={0: datefunc}, # Formatting of column 0 
             dtype=float, # All values are floats 
             usecols=(0,1,2), #Leer las tres primeras columnas de datos.txt 
             unpack=True) # Unpack to several variables 

    # Configure x-ticks 
    ax1.clear() 

    ax1.set_xticks(dates) # Tickmark + label at every plotted point 
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y %H:%M')) 


    ax2 = ax1.twinx() 

    fig.tight_layout() 

fig = plt.figure() 
ax1 = fig.add_subplot(111) 
ani = animation.FuncAnimation(fig, animate, fargs=(fig, ax1), interval=1000) 
plt.show() 

Мои данные (datosPlot.txt) выглядит следующим образом:

14-01-2017_14:01:16 1 16 
14-01-2017_14:01:19 14 22 
14-01-2017_14:01:22 2 17 
14-01-2017_14:01:25 4 19 
14-01-2017_14:01:28 6 24 
14-01-2017_14:01:31 12 19 
14-01-2017_14:01:34 4 18 
14-01-2017_14:01:37 9 20 

Первый столбец является осью X (date_time), второй столбец pH , третья колонка - Температура.

Я пытался добавить ax2.clear() до и после звонка ax2 = ax1.twinx(), но он не работает. Как я могу его очистить, поскольку я могу с ax1?

Вот как это выглядит, когда я не добавляйте ax2.clear(): enter image description here

+0

Вы должны добавить фиктивные данные в сценарий примера вместо чтения из '' datosPlot.txt'', который у вас нет, кроме вас. Также удалите все форматирование по оси x, так как это, вероятно, не связано. См. Http://stackoverflow.com/help/mcve для получения дополнительной информации –

+0

также, почему параметр 'ax1' является вашей функцией, когда вы никогда не используете его? возможно, как 'ax1', так и' ax2' должны быть параметрами вашей функции, и функция не должна нести ответственность за их создание. –

+0

Я добавил некоторые фиктивные данные, как вы предложили, @PaulH, также я удалил ненужную информацию. О вашем втором комментарии, я не уверен, что понимаю. Насколько мне известно, «ax1» и «ax2» необходимы для построения обеих линий (pH и темп) с их собственными масштабами (слева и справа от graph) – Ramirous

ответ

3

Пытаться создать ось за пределами вашей анимации и использовать только в качестве небольшого кода, что вам действительно нужно в каждом шаге анимации.

Ниже приведен пример запуска, в котором вам нужно будет заменить функцию чтения em.genfromtxt() на ваш первоначальный вызов np.genfromtxt(....).

import matplotlib.pyplot as plt 
import matplotlib.dates as mdates 
from datetime import datetime 
import numpy as np  
import matplotlib.animation as animation 


##### Emulator to generate data ######### 
class emulator(): 
    def __init__(self): 
     self.dates = [] 
     self.levels = [] 
     self.temp = [] 

    def genfromtxt(self): 
     self.dates.append(mdates.date2num(datetime.now())) 
     self.levels.append(np.random.randint(1,14)) 
     self.temp.append(np.random.rand(1)*16+4) 
     return self.dates, self.levels, self.temp 

em = emulator() 
##### End of Emulator to generate data ######### 




# Converter function 
datefunc = lambda x: mdates.date2num(datetime.strptime(x, '%d-%m-%Y_%H:%M:%S')) 


def animate(i): 
    # Read data from 'file.dat' 
    # instead we use an emulator here, replace with your original genfromtxt function 
    dates, levels, temp = em.genfromtxt() 

    # Configure x-ticks 
    ax1.clear() 
    ax2.clear() 
    ax1.grid(True) 
    ax2.grid(True) 

    ax1.plot_date(dates, levels, ls='-', marker='.', color='red', label='pH') 
    ax2.plot_date(dates, temp, ls='-', marker='.', color='blue', label='Temperatura C') 

    ax1.set_xticks(dates) # Tickmark + label at every plotted point 
    ax1.locator_params(axis='x',nbins=10) 
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y %H:%M')) 
    #Leyendas 
    lines = ax1.get_lines() + ax2.get_lines() 
    plt.legend(lines, [l.get_label() for l in lines], loc=2) 

    fig.autofmt_xdate(rotation=45) 
    fig.tight_layout() 



fig = plt.figure() 

# we create both axes outside the animation and already set those parameters 
# which stay the same throughout the animation. 
ax1 = fig.add_subplot(111) 

ax1.set_title('pH y Temp') 
ax1.set_ylabel('pH') 

ax2 = ax1.twinx() # This should happen outside the animation already. 
ax2.set_ylabel('Temperatura C')  

ani = animation.FuncAnimation(fig, animate, interval=1000) 
plt.show() 
+0

Это отлично работает (он больше не запутывается), единственное, что он не показывает метки ('ax1.set_ylabel (' pH ') 'и' ax2.set_ylabel (' Temperatura C ') '), любая идея, почему? – Ramirous

+0

Я только что понял, я переместил эти метки сразу после 'ax1.plot_date (...)' и 'ax2.plot_date (...)', работает отлично! Спасибо! – Ramirous