Jump to content
Fórum Script Brasil
  • 0
Sign in to follow this  
Alexandre Stoiev

AJUDA PYTHON LOG E gráficos URGENTE

Question

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from datetime import datetime
import serial
import time

style.use('ggplot')
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

porta = 'com7'
baud_rate = 9600

opçao = input("Iniciar verificação de temperatura ? S ou N ")

if opçao == "S":

    tempo = int(input("Informe o intervalo entre cada leitura: "))

    objeto_porta = serial.Serial(porta, baud_rate)
    objeto_porta.flushInput()

    arquivo = open("LOG.txt", "a+")

    while True:
        # Cria o objeto_hoje, pega os valores de
        # dia, mes, ano e horario, converte para string
        objeto_hoje = datetime.today()
        dia = str(objeto_hoje.day)
        mes = str(objeto_hoje.month)
        ano = str(objeto_hoje.year)
        horario = str(objeto_hoje.strftime("%X"))

        # Le os valores passados pelo arduino
        temperatura = str(objeto_porta.readline())

        arquivo.write(horario)
        arquivo.write("  ")
        arquivo.write(temperatura)
        arquivo.write("\n")

        def animate(i):
            arquivo = open("LOG.txt", "r").readline()
            lines = arquivo.split("\r\n")
            x = []
            y = []
            for line in lines:
                X, Y = line.split("  ")
                x.append(X)
                y.append(Y)

                ax1.clear()
                ax1.plot(x, y)


        ani= animation.FuncAnimation(fig,  animate, interval=tempo*1000)

        plt.show()

else:

    print("Saindo...")

Olá,  sou iniciante e estou desenvolvendo um sistema de controle de temperatura visual para um trabalho escolar, porem me deparei com o seguinte inconveniente

Para gerar os gráficos estou usando a blibioteca matplotlib e para os dados lidos pelo sensor de temperatura eu utilizo um simples arquivo txt, como um log. Ou seja o conceito do projeto é 

Ler dados do sesor -> armazenar -> plottar o grafico. devido ao meu log funcionar dentro de um WHILE ao chegar no comando que chama o pyplot, plt.show(), ele não retorna ao inicio do loop dessa forma só a primeira leitura do sensor é armazenada e plottada 

 

Gostaria muito de ajuda pois sou um estudante por conta propria e não consigo visualizar a solucao para este problema

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites

21 answers to this question

Recommended Posts

  • 0

experimente isolar partes do codigo

pode começar fazendo um sensor fake e conferir se o restante do codigo esta agindo de acordo

depois testar a leitura do sensor em uns script separado

Share this post


Link to post
Share on other sites
  • 0
13 horas atrás, ArteEN disse:

    while True:
        # Cria o objeto_hoje, pega os valores de
        # dia, mes, ano e horario, converte para string
        arquivo = open("LOG.txt", "a+")
        
        objeto_hoje = datetime.today()
        dia = str(objeto_hoje.day)
        mes = str(objeto_hoje.month)
        ano = str(objeto_hoje.year)
        horario = str(objeto_hoje.strftime("%X"))

        # Le os valores passados pelo arduino
        temperatura = str(objeto_porta.readline())

        arquivo.write(horario)
        arquivo.write("  ")
        arquivo.write(temperatura)
        arquivo.write("\n")

        def animate(i):
            arquivo = open("LOG.txt", "r").readline()
            lines = arquivo.split("\r\n")
            x = []
            y = []
            for line in lines:
                X, Y = line.split("  ")
                x.append(X)
                y.append(Y)

                ax1.clear()
                ax1.plot(x, y)


        ani= animation.FuncAnimation(fig,  animate, interval=tempo*1000)

        plt.show()

experimente isolar partes do codigo

pode começar fazendo um sensor fake e conferir se o restante do codigo esta agindo de acordo

depois testar a leitura do sensor em uns script separado

Olá, eu fiz como voce recomendou e separei o meu codigo em 2 scripts, um para cada função, e os dois funcionam corretamente.

No meu codigo de programa "completo" eu penso que identifiquei o problema mas não sei como resolve-lo.

Devido ao meu programa funcionar em um loop infinito para atulizar a leitura do log ao chegar no parte do codigo que chama o grafico         plt.show()        ele não recomeca o loop pois essa seria uma "funçao" que não tem fim, ou seja é o programa esta realizando a tarefa porem ela não acaba e o loop não recomeça 

Como eu posso resolver esse problema ? Talvez passar o loop que registra o log para dentro do mesmo evento que atualiza o grafico ? 

 

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites
  • 0

Dei uma olhada na documentação, a meu ver o problema esta como você esta usando a função FuncAnimation

Se você olha na documentação vera o parâmetro intervalo, ele faz parecer que a própria função já é um loop infinito, e o resultado do seu código é um loop infinito dentro de outro loop infinito

Então vem a primeira interação do primeiro loop infinito, e começa o segundo loop, e como o segundo loop nunca termina, o primeiro loop não prossegue

Share this post


Link to post
Share on other sites
  • 0

 

 

 

13 minutos atrás, Alexandre Stoiev disse:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from datetime import datetime
import serial
import matplotlib.dates as mdates
import time

style.use('ggplot')
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

porta = 'com7'
baud_rate = 9600
x = []
y = []

opçao = input("Iniciar verificação de temperatura ? S ou N ")

if opçao == "S":

    tempo = int(input("Informe o intervalo entre cada leitura: "))

    objeto_porta = serial.Serial(porta, baud_rate)
    objeto_porta.flushInput()



    while True:


        def animate(i):

            arquivo = open("LOG.txt", "a+")

            objeto_hoje = datetime.today()
            horario = str(objeto_hoje.strftime("%H"))
            minuto = str(objeto_hoje.strftime("%M"))
            segundos = str(objeto_hoje.strftime("%S"))

            temperatura = str(objeto_porta.readline())

            arquivo.write(horario)
            arquivo.write(".")
            arquivo.write(minuto)
            arquivo.write(".")
            arquivo.write(segundos)
            arquivo.write(",")
            arquivo.write(temperatura)
            arquivo.write("\n")

            arquivo.close()

            arquivo = open("LOG.txt", "r")

            for line in arquivo:
                line = line.strip("\r\n'")
                X, Y = line.split(",b'")
                x.append(X)
                y.append(Y)

                ax1.clear()
                ax1.plot(x, y)



            arquivo.close()




        ani= animation.FuncAnimation(fig,  animate, interval=tempo*1000)

        plt.show()
26 minutos atrás, ArteEN disse:

Dei uma olhada na documentação, a meu ver o problema esta como você esta usando a função FuncAnimation

Se você olha na documentação vera o parâmetro intervalo, ele faz parecer que a própria função já é um loop infinito, e o resultado do seu código é um loop infinito dentro de outro loop infinito

Então vem a primeira interação do primeiro loop infinito, e começa o segundo loop, e como o segundo loop nunca termina, o primeiro loop não prossegue

após muitos testes nesse script eu cheguei a essa mesma conclusão então eu alterei o código para que todo o loop do programa estivesse contido dentro desse evento dessa forma o programa executa o loop sempre que o evento de animação é chamado. o  programa em si funcionou de maneira aceitável porem agora eu estou tendo problemas técnicos com o matplotlib

 

como minhas leituras são realizadas a cada um segundo, o gráfico fica saturado no eixo x de informações(que seriam o horário) porem como elas são strings ( exemplo 15:13:00)  ele tenta mostrar todos os horários de leitura ao invés de "criar uma média" e adaptar a visualização

 

ate agora não consegui achar uma solução para esse problema talvez você possa me ajudar

existe alguma maneira de transformar o horário em um float (pois até onde sei é o único modo de numeros em que o gráfico ajusta os valores de exibição)  ou então uma função que interprete o horário corretamente ?

 

 

 

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites
  • 0

tem uma função que não lembro qual agora, que retorna a hora atua em segundos, com ela você pode fazer a diferença entre duas leituras, você já esta usando a biblioteca time, esta função deve estar junto

 

Share this post


Link to post
Share on other sites
  • 0

Eu já havia tentado algo parecido porem apesar de funcionar não é oque eu preciso. Mas obrigado por ajudar

Eu preciso manter o formato HH:MM:SS pois é necessario para o trabalho que vai ser feito, porem dessa maneira o gráfico não se ajusta sozinho 

Até agora não achei uma soluçao para essa problema. Talvez uma outra biblioteca de plot ? Ou então um grafico que se extenda no eixo x e uma barra de rolagem para viajar por ele completo ?

So achei na internet alguns poucos exemplos assim e não consegui formar nenhum script dessa maneira

Meu problema não é adquirir os dados nesse  formato de hora/minuto/segundo mas sim fazer o matplotlib se ajustar a eles

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites
  • 0

uma solução facil é criar um objeto ou lista onde ele tenha os dois valores

 

l = ['00:01:00', 60]
l = ['00:02:00', 120]

#ou

class Horario:
  def __init__(self, e, n):
    self.extenso = e
    self.numeral = n
    
h = Horario('00:01:00', 60)

com isso você pode usar o valor dos segundos para entrar como paramentro de posição no grafigo, e o formato de hora para exibição, porem é apenas suposição minha, não tenho o matplot istalado para conferir se é possivel, vou ficar devendo

Share this post


Link to post
Share on other sites
  • 0

eu estou ficando doido com isso mas agradeço de verdade a ajuda. eu vou procurar saber se isso é possível.

eu não estou conseguindo extrair as informações mesmo dos exemplos do site do matplot que eu preciso. Essa biblioteca é muito extensa portanto acho que deve ter algo sobre oque eu preciso mas não sei ainda como aplicar 

caso você queira dar uma olhada nos exemplos ou na documentação dessa biblioteca para me ajudar vou deixar o link https://matplotlib.org/index.html, mas já agradeço pela ajuda com o primeiro problemas do loop foi uma baita de uma ajuda amigo. 

Share this post


Link to post
Share on other sites
  • 0

eu estava dando uma olhada, bem me ocorreu uma ideia, você esta fazendo um grafico de linha?

vi que tem uma função onde redesenha o grafico, imagino que você pode criar uma lista com um range de 10 ou 20 posições, e ir atualizando essa lista como o ultimo valor, e atualizar o grafico em seguida

 

l = [0 for x in range(10)]

for i in range(20):
  print(l)
  l.pop(0)
  l.append(int(input('leitura')))
  

veja o exemplo de como a lista vai se atualizando, claro que funcionando você devera tirar do loop for

Share this post


Link to post
Share on other sites
  • 0

Sim, a ideia é ótima mas o projeto que me foi passado exige que a temperatura seja lida em tempo real mas que armazene os dados do período todo em que foi acionado(sendo exibidos para o operador) no dia para garantir a conformidade do equipamento para futuras vistorias.

o gráfico começa, tem que se atualizar ao vivo, mas sem parar de mostrar as informações anteriores, e então ser salvo ao final do dia. é um projeto bem complicadinho estou nisso a semanas já.

eu acebei de olhar algumas documentações e achei uma falando sobre um modo de plot chamado xdate, que reconhece como datas do matplot e não como strings poderia funcionar e também nessa mesma biblioteca uma função chamada date2num que transforma objetos de datetime em objetos para o matplot dates date2numxdate

apesar de ter encontrado ainda não entendi como usa-los corretamente no meu código, dê uma olhada nos links desses se puder são funcionalidades que me parecem bem interessantes. 

 

ta vendo oque acontece no eixo x ? é isso que eu quero evitar 

 

Captura de Tela (11).png

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites
  • 0

nesse segundo link diz que funciona igual ao matplotlib.pyplot.plot, só que usando datas

 

acho que é para ficar no lugar do fig = plt.figure()

como fig = plt.plot_date()

ou

ax1.plot(x, y) para ax1.plot_date(x, y)

é o que penso vendo a documentação e seu codigo antigo

Share this post


Link to post
Share on other sites
  • 0
 for line in arquivo:
                line = line.strip("\r\n'")
                X, Y = line.split(",b'")
                x.append(X)
                y.append(Y)

                plt.clear()
                plt.plot_date(x, y, xdate=True, ydate=False)

a única mudança que funcionou foi essa parte do final para o xdate, mas ai  o meu código da erro de Split  ele diz que esperava por 2 valores em X, Y e só recebeu um agora eu fiquei confuso

se eu mudo no fig ou no ax1 ele diz que subplots não tem esses tributos

será que agora ele esta esperando um modelo de data no x e o que eu estou enviando não é aceito ? por isso o erro ?

 

 

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites
  • 0

acho que achei sua solução, de uma olhada

https://jakevdp.github.io/PythonDataScienceHandbook/04.10-customizing-ticks.html

3 minutos atrás, Alexandre Stoiev disse:
 X, Y = line.split(",b'")
ValueError: not enough values to unpack (expected 2, got 1)

ele esta apontando um erro antes do Split ?

 

erro meu, não olhei o append(X) ou (Y)

na mensagem de erro não aponta a linha?

Share this post


Link to post
Share on other sites
  • 0
12 minutos atrás, ArteEN disse:

acho que achei sua solução, de uma olhada

https://jakevdp.github.io/PythonDataScienceHandbook/04.10-customizing-ticks.html

erro meu, não olhei o append(X) ou (Y)

na mensagem de erro não aponta a linha?

desculpe foi um erro meu eu coloquei sem querer um caractere errado no log 

12 minutos atrás, ArteEN disse:

acho que achei sua solução, de uma olhada

https://jakevdp.github.io/PythonDataScienceHandbook/04.10-customizing-ticks.html

erro meu, não olhei o append(X) ou (Y)

na mensagem de erro não aponta a linha?

quanto a este, qual você acha que resolvera meu problema ? oque elimina as legendas não serve pois eu preciso delas

vou salvar esse link pode ser muito útil essas informações de formatação mais a frente

 

estou achando que não existe uma função nesse biblioteca que ajuste as datas assim como faz com os números em float

 

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites
  • 0

pelo o que eu vi, tem um comando que limita a informação no eixo

veja os exemplos 7 e 8

Share this post


Link to post
Share on other sites
  • 0
13 minutos atrás, ArteEN disse:

pelo o que eu vi, tem um comando que limita a informação no eixo

veja os exemplos 7 e 8

finalmente acho que isso finalmente resolve meu problema, vou testar AGORA se funcionar você vai ser meu herói KKKK

13 minutos atrás, ArteEN disse:

pelo o que eu vi, tem um comando que limita a informação no eixo

veja os exemplos 7 e 8

Cara você é fenomenal isso realmente resolveu meus problemas ( vejamos se não vão aparecer mais KKKK) obrigado pela ajuda

Ah, faltou só uma coisa, devido a minha temperatura vir por serial ela fica salva com esse /r/n sabe como resolver isso ?

Edited by Alexandre Stoiev

Share this post


Link to post
Share on other sites
  • 0

você pode usar str.replace('', '/r/n')

ou

fatiar str[:str.rfind('/r')]

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  



  • Forum Statistics

    • Total Topics
      148083
    • Total Posts
      643273
×
×
  • Create New...