python (pandas?) live plot - python

I have been trying to get an updated plot from a pandas dataframe without success. My problem: the plot window does not appear (it is not hidden - I am sure about that).
I already tried to rebuild and change different solutions from stackoverflow. My most recent try is based on this post. Pure copy,paste does work, so the problem needs to be in my modifications.
I changed it to this as I want to update it automatically every second.
import serial as s
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from time import sleep
data = pd.DataFrame(np.random.random((10,10))) # I want to use pandas because
# of easier timestamp handling
fig, ax = plt.subplots()
ax.set(title='title')
im = ax.imshow(data)
while True:
im.set_data(np.random.random((10,10)))
print "hello" #just to see if sth happens
fig.canvas.draw()
sleep(1)
plt.show()
Just to explain: Later I want to read data from serial ports and feed them to the plot to get my data visualized.
Well, what you expect: the provided code does print hello each second but does not show me any plot. Any ideas? I am out of them.
By the way: I am surprised that there is no "easy, straight forward" solution for this kind of problem to be found. I can imagine, there is some people who are trying to do updated plots?!

you can use the package drawnow
from pylab import * # import matplotlib before drawnow
from drawnow import drawnow, figure
from time import sleep
import numpy as np
def draw_fig_real():
imshow(data, interpolation='nearest')
data = np.random.random((10,10))
figure()
for i in range(10):
data = np.random.random((10,10))
sleep(0.5)
drawnow(draw_fig_real)
Hope this helps

Related

Suppress display of final frame in matplotlib animation in jupyter

I am working on a project that involves generating a matplotlib animation using pyplot.imshow for the frames. I am doing this in a jupyter notebook. I have managed to get it working, but there is one annoying bug (or feature?) left. After the animation is created, Jupyter shows the last frame of the animation in the output cell. I would like the output to include the animation, captured as html, but not this final frame. Here is a simple example:
import numpy as np
from matplotlib import animation
from IPython.display import HTML
grid = np.zeros((10,10),dtype=int)
fig1 = plt.figure(figsize=(8,8))
ax1 = fig1.add_subplot(1,1,1)
def animate(i):
grid[i,i]=1
ax1.imshow(grid)
return
ani = animation.FuncAnimation(fig1, animate,frames=10);
html = HTML(ani.to_jshtml())
display(html)
I can use the capture magic, but that suppresses everything. This would be OK, but my final goal is to make this public, via binder, and make it as simple as possible for students to use.
I have seen matplotlib animations on the web that don't seem to have this problems, but those used plot, rather than imshow, which might be an issue.
Any suggestions would be greatly appreciated.
Thanks,
David
That's the answer I got from the same thing I was looking for in 'jupyter lab'. Just add plt.close().
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML
grid = np.zeros((10,10),dtype=int)
fig1 = plt.figure(figsize=(8,8))
ax1 = fig1.add_subplot(1,1,1)
def animate(i):
grid[i,i]=1
ax1.imshow(grid)
return
ani = animation.FuncAnimation(fig1, animate,frames=10);
html = HTML(ani.to_jshtml())
display(html)
plt.close() # update

According to tutorial fig did not need to be used, but receiving unused variable error in vscode

I got the following code from the sentdex Machine Learning for Forex tutorial
Whenever I run this code, an empty graph with no data plotted pops up. The warning also shows that the variable fig is unused.
I've deleted the fig variable, tried importing pandas and running a version of the code using that syntax, and tried changing the backend used for matplotlib.
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import matplotlib.dates as mdates
import numpy as np
def graphRawFX():
date,bid,ask = np.loadtxt('GBPUSD1d.txt', unpack=True, delimiter=',',
converters={0:mdates.strpdate2num('%Y%m%d%H%M%S')})
fig = plt.figure(figsize=(10,7))
ax1 = plt.subplot2grid((40,40), (0,0), rowspan=40, colspan=40)
ax1.plot (date,bid)
ax1.plot (date,ask)
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S'))
plt.grid(True)
plt.show(True)
To display a graph that shows data plotted appropriately.
As your code stands right now, it basically, functionally, is this:
import matplotlib.pyplot as plt
plt.grid(True)
plt.show(True)
It imports plt from matplotlib, then creates a grid and shows it. Nothing else in the code is being used.
All the work for plotting data would take place within graphRawFX() which is not ever being called.
The last two lines, plt.grid(True) and plt.show(True), are improperly indented. They should be indented to lie within the function.
After that, you simply need to add graphRawFX() to the end of your code, without any indentation, to call the function and plot your data.
Here's a slightly cleaned up version of your code for better readability, and to ensure indentation is correct for all of the lines.
Note that import matplotlib and import matplotlib.ticker as mticker have been removed as well, as in this particular code, they're not necessary.
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
def graphRawFX():
date, bid, ask = np.loadtxt(
'GBPUSD1d.txt',
unpack=True,
delimiter=',',
converters={
0: mdates.strpdate2num('%Y%m%d%H%M%S')})
ax1 = plt.subplot2grid((40, 40), (0, 0), rowspan=40, colspan=40)
ax1.plot(date, bid)
ax1.plot(date, ask)
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M:%S'))
plt.grid(True)
plt.show(True)
graphRawFX()
Note that the above code is only going to work in Python 2. To get it going in Python 3, take a look at this answer: https://stackoverflow.com/a/16496215/214150

How to make live graphs plotted in a single one graph?

I'm trying to show real-time graphs(dynamic plotting) using python. However, the result didn't show in a single one graph, but generate a new one each second, which didn't mean updating live graph. How can I solve it? Is there any problem in my code?
import serial
import time
import matplotlib.pyplot as plt
from drawnow import drawnow
DataList = []
pcs = serial.Serial('COM4', baudrate = 9600, timeout = 1)
time.sleep(3)
plt.ion()
def makeFig():
plt.plot(DataList, 'rd-')
def getValues():
pcs.write(b"MEASure:VOLTage:DC?\n")
pcsData = pcs.readline().decode('ascii').split('\n\r')
DataList.append(float(pcsData[0]))
while(1):
getValues()
drawnow(makeFig)
plt.pause(.000001)
The result snapshot:
the drawnow called in this way is designed as one-shot draw. See if drawnow(caller, show_once=True) corrects your problem, else you may need to look elsewhere - such as using alternative plotting functions:
How do I plot in real-time in a while loop using matplotlib?

How can I use the display() function in Microsoft Azure Notebook

I am unable to display the .png file created by pyplot. I created the file in Microsoft Azure Jupyter Notebook. os.listdir() returns xx.png, so I know that the file was created. Yet, display(Image("xx.png")) does not show the image. I have read about ten related posts on stackoverflow and tried numerous variations of the command, but nothing works.
When I reproduce the problem on my local computer it works fine.
This question is a re-write of a previous question that was marked as duplicate and left to die. I hope that this post will make the question easier to understand.
Following is the code used to create the file:
from IPython.display import display
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import os
y = [2,4,6,8,10,12,14,16,18,20]
x = np.arange(10)
fig = plt.figure()
ax = plt.subplot(111)
ax.plot(x, y, label='$y = numbers')
plt.title('Legend inside')
ax.legend()
fig.savefig('xx.png')
There are two ways given the code you have to show the image.
1) You can call %matplotlib inline at the top of the notebook. This will inline graphics and you will see the image by calling fig
2) You can from IPython.display import Image and Image('xx.png') and the image should be displayed.
It appears you are missing an import statement, try :
from Ipython.display import Image
display(Image("xx.png"))

Why is Jupyter Notebook creating duplicate plots when making updating plots

I'm trying to make plots in a Jupyter Notebook that update every second or so. Right now, I just have a simple code which is working:
%matplotlib inline
import time
import pylab as plt
import numpy as np
from IPython import display
for i in range(10):
plt.close()
a = np.random.randint(100,size=100)
b = np.random.randint(100,size=100)
fig, ax = plt.subplots(2,1)
ax[0].plot(a)
ax[0].set_title('A')
ax[1].plot(b)
ax[1].set_title('B')
display.clear_output(wait=True)
display.display(plt.gcf())
time.sleep(1.0)
Which updated the plots I have created every second. However, at the end, there is an extra copy of the plots:
Why is it doing this? And how can I make this not happen? Thank you in advance.
The inline backend is set-up so that when each cell is finished executing, any matplotlib plot created in the cell will be displayed.
You are displaying your figure once using the display function, and then the figure is being displayed again automatically by the inline backend.
The easiest way to prevent this is to add plt.close() at the end of the code in your cell.
Another alternative would be to add ; at the end of the line! I am experiencing the same issue with statsmodels methods to plot the autocorrelation of a time series (statsmodels.graphics.tsaplot.plot_acf()):
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(daily_outflow["count"]);
Despite using %matplotlib inline, it's not working for some libraries, such as statsmodels. I recommend always use plt.show() at the end of your code.

Categories