I want to Animate a 3D Polar Plot and export it, because my Computer has not enough CPU Power for displaying it with plt.show() (If you have a good solution how to calculate it before showing, I would appreciate it, too)
Unfortunatly the export does not work and I do not know why. To my mind this should work.
Is it possible that my Python IDE(PyCharm) oder my Python Version(2.7) is responsible?
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
from IPython import display
psi_vec = np.arange(0, 2 * np.pi, 0.1)
radius = np.arange(0,1,0.05)
Z_ones = np.ones(63)
def animate(time):
X = np.zeros((np.size(psi_vec), np.size(radius)))
Y = np.zeros((np.size(psi_vec), np.size(radius)))
Z = np.zeros((np.size(psi_vec), np.size(radius)))
for i in range(np.size(radius)):
X[:,i] = np.cos(psi_vec) * radius[i]
Y[:,i] = np.sin(psi_vec) * radius[i]
Z[:,i] = np.sin(time) * i * Z_ones
line = ax.plot_surface(X, Y, Z,color= 'b')
return line
fig = plt.figure()
ax = p3.Axes3D(fig)
anim = animation.FuncAnimation(fig, animate, frames = 15, interval = 500)
video = anim.to_html5_video()
html = display(video)
display.display(html)
The Error Message is:
Traceback (most recent call last):
File "/home/alexander/Dokumente/PetersHe (vectors)/animation.py", line 48, in <module>
video = anim.to_html5_video()
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/matplotlib/animation.py", line 1353, in to_html5_video
self.save(f.name, writer=writer)
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/matplotlib/animation.py", line 1200, in save
writer.grab_frame(**savefig_kwargs)
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/contextlib.py", line 35, in __exit__
self.gen.throw(type, value, traceback)
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/matplotlib/animation.py", line 241, in saving
self.finish()
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/matplotlib/animation.py", line 367, in finish
self.cleanup()
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/matplotlib/animation.py", line 405, in cleanup
out, err = self._proc.communicate()
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/subprocess32.py", line 748, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/subprocess32.py", line 1557, in _communicate
orig_timeout)
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/subprocess32.py", line 1613, in _communicate_with_poll
register_and_append(self.stdout, select_POLLIN_POLLPRI)
File "/home/alexander/anaconda2/envs/PyEnv/lib/python2.7/site-packages/subprocess32.py", line 1592, in register_and_append
poller.register(file_obj.fileno(), eventmask)
ValueError: I/O operation on closed file
Process finished with exit code 1
Thank You!
Related
I want to plot the close price of INS as below and it works. Then I want to add the cursor when hovering on the graph. I follow the demo from https://matplotlib.org/3.1.0/gallery/misc/cursor_demo_sgskip.html and that is what I want.
But when I added these lines into the code, it shows value error. Initially I use epoch time as x-axis and I thought that is the problem, so I convert epoch time to datetime but it is still not working and plot nothing.
snap_cursor = SnaptoCursor(ax, secs, df['close'])
fig.canvas.mpl_connect('motion_notify_event', snap_cursor.mouse_move)
Traceback (most recent call last): File
"c:\Users\Sam.vscode\extensions\ms-python.python-2020.6.89148\pythonFiles\ptvsd_launcher.py",
line 48, in
main(ptvsdArgs) File "c:\Users\Sam.vscode\extensions\ms-python.python-2020.6.89148\pythonFiles\lib\python\old_ptvsd\ptvsd_main_.py",
line 432, in main
run() File "c:\Users\Sam.vscode\extensions\ms-python.python-2020.6.89148\pythonFiles\lib\python\old_ptvsd\ptvsd_main_.py",
line 316, in run_file
runpy.run_path(target, run_name='main') File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\runpy.py",
line 263, in run_path
pkg_name=pkg_name, script_name=fname) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\runpy.py",
line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\runpy.py",
line 85, in _run_code
exec(code, run_globals) File "c:\Users\Sam\OneDrive\Project\stock\test.py", line 89, in
plt.gcf().autofmt_xdate() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\figure.py",
line 632, in autofmt_xdate
for label in self.axes[0].get_xticklabels(which=which): File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axes_base.py",
line 3355, in get_xticklabels
return self.xaxis.get_ticklabels(minor=minor, which=which) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py",
line 1320, in get_ticklabels
return self.get_majorticklabels() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py",
line 1276, in get_majorticklabels File
"C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py",
line 1431, in get_major_ticks
numticks = len(self.get_majorticklocs()) File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\axis.py",
line 1348, in get_majorticklocs
return self.major.locator() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\dates.py",
line 1338, in call
self.refresh() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\dates.py",
line 1364, in refresh
dmin, dmax = self.viewlim_to_dt() File "C:\Users\Sam\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\dates.py",
line 1098, in viewlim_to_dt
.format(vmin))
ValueError: view limit minimum -36879.777083333334 is less than 1 and
is an invalid Matplotlib date value. This often happens if you pass a
non-datetime value to an axis that has datetime units
class SnaptoCursor(object):
"""
Like Cursor but the crosshair snaps to the nearest x, y point.
For simplicity, this assumes that *x* is sorted.
"""
def __init__(self, ax, x, y):
self.ax = ax
self.lx = ax.axhline(color='k') # the horiz line
self.ly = ax.axvline(color='k') # the vert line
self.x = x
self.y = y
# text location in axes coords
self.txt = ax.text(0.7, 0.9, '', transform=ax.transAxes)
def mouse_move(self, event):
if not event.inaxes:
return
x, y = event.xdata, event.ydata
indx = min(np.searchsorted(self.x, x), len(self.x) - 1)
x = self.x[indx]
y = self.y[indx]
# update the line positions
self.lx.set_ydata(y)
self.ly.set_xdata(x)
self.txt.set_text('x=%1.2f, y=%1.2f' % (x, y))
print('x=%1.2f, y=%1.2f' % (x, y))
self.ax.figure.canvas.draw()
data = td.pricehistory("INS")
df = pd.DataFrame(data['candles'])
df['datetime'] = df.apply(lambda x: datetime.datetime.fromtimestamp(x['datetime']/1000),axis=1)
secs = df['datetime']
fig, ax = plt.subplots(1, 1)
ax.plot(secs,df['close'])
snap_cursor = SnaptoCursor(ax, secs, df['close'])
fig.canvas.mpl_connect('motion_notify_event', snap_cursor.mouse_move)
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%d-%m-%y %H:%M:%S')
plt.gca().xaxis.set_major_formatter(myFmt)
plt.show()
I'm not familiar with SnaptoCursor, but have you considered using plotly instead?
Saves many lines of code and is very user-friendly:
# install plotly library
!pip install plotly
# import express module
import plotly.express as px
# plot interactive line chart
fig = px.line(data=df, x="datetime", y="close")
fig.show()
It's very flexible too. Here is the documentation: https://plotly.com/python/line-charts/
You can interact with the plots using the cursor too, for example:
Hope this helps, though of course it's different to what you were trying to do!
I am new to python so I understand that this may be a stupid question, but I am having issues animating this. I can't see what the error is. I get this error
TypeError: f() missing 1 required positional argument: '
I want to use matplotlib when animating, because I have not downloaded scitools.
Any help at all would be very much appriciated
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
x = np.linspace(-6, 6)
tmax = 1
tmin = -1
t = np.linspace(-1, 1)
def f(x, t):
term = (np.exp(-1*(x-3*t)**2))*np.sin(3*np.pi*(x-t))
return term
max_f = f(x[-1], t[-1])
plt.ion()
y = f(x, tmax)
lines = plt.plot(x, y)
plt.axis([x[0], x[-1], -0.1, max_f])
plt.xlabel('x')
plt.ylabel('f')
counter = 0
for ts in t:
y = f(x, t)
lines[0].set_ydata(y)
plt.legend(['ts=%4.2f' % ts])
plt.draw()
plt.savefig('tmp_%04d.png' % counter)
counter += 1
fig = plt.figure()
anim = animation.FuncAnimation(fig, f, interval = 1000, blit=True)
fig = plt.figure()
plt.axis([x[0], x[-1], -0.1, max_f])
lines = plt.plot([], [])
plt.xlabel('x')
plt.ylabel('f')
plt.show()
EDIT, full traceback:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\tkinter__init__.py", line 1699, in call
return self.func(*args)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\tkinter__init__.py", line 745, in callit
func(*args)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 370, in idle_draw
self.draw()
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 351, in draw
FigureCanvasAgg.draw(self)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backends\backend_agg.py", line 464, in draw
self.figure.draw(self.renderer)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\figure.py", line 1151, in draw
self.canvas.draw_event(renderer)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\backend_bases.py", line 1823, in draw_event
self.callbacks.process(s, event)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\cbook.py", line 554, in process
proxy(*args, **kwargs)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\cbook.py", line 416, in call
return mtd(*args, **kwargs)
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 881, in _start
self._init_draw()
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1540, in _init_draw
self._draw_frame(next(self.new_frame_seq()))
File "C:\Users\me\AppData\Local\Programs\Python\Python36-32\lib\site-packages\matplotlib\animation.py", line 1562, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)
TypeError: f() missing 1 required positional argument: 't'
As said, this is not really about the error, you can easily prevent that by supplying some value for t as fargs in FuncAnimation. However, this will not lead to the code producing an animation at all and hence as said, start with the exmaple add your functions and code step by step and see what happens.
This will eventually lead to something like the following:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(-6, 6)
tmax = 1
tmin = -1
t = np.linspace(-1, 1)
def f(x, t):
term = (np.exp(-1*(x-3*t)**2))*np.sin(3*np.pi*(x-t))
return term
y = f(x, tmax)
lines = plt.plot(x, y)
plt.axis([x[0], x[-1], -1, 1])
plt.xlabel('x')
plt.ylabel('f')
counter = [0]
def animate(ts):
y = f(x, ts)
lines[0].set_ydata(y)
plt.legend(['ts=%4.2f' % ts])
#plt.savefig('tmp_%04d.png' % counter)
counter[0] += 1
anim = animation.FuncAnimation(plt.gcf(), animate, frames = t, interval = 1000)
plt.show()
I am trying to pull data from different end points using my python code and feeding the same data to plot a graph using matplotlib. I dont have any problem in reading the data but when i invoke the methods to plot graph by feeding the data i see intermittent error caused by matplot lib. below are the error details.
Traceback (most recent call last):
File "C:\Python35\lib\site-packages\slackbot\dispatcher.py", line 55, in _dispatch_msg_handler
func(Message(self._client, msg), *args)
File "C:\PycharmProjects\SlackBot\src\plugins\bot_response.py", line 248, in checkmarx
draw_chart.riskscore_bar(top_riskscore, project_name, "output_files", "riskscore_bar.png")
File "C:\PycharmProjects\SlackBot\src\drawchart.py", line 111, in riskscore_bar
fig, ax = plt.subplots()
File "C:\Python35\lib\site-packages\matplotlib\pyplot.py", line 1202, in subplots
fig = figure(**fig_kw)
File "C:\Python35\lib\site-packages\matplotlib\pyplot.py", line 535, in figure
**kwargs)
File "C:\Python35\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 81, in new_figure_manager
return new_figure_manager_given_figure(num, figure)
File "C:\Python35\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 98, in new_figure_manager_given_figure
icon_img = Tk.PhotoImage(file=icon_fname)
File "C:\Python35\lib\tkinter\__init__.py", line 3403, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Python35\lib\tkinter\__init__.py", line 3359, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
RuntimeError: main thread is not in main loop
I have tried looking into other cases from stackoverflow with same error messages, but it didnt help me fix this. Below is my code snippet that invokes an error.
def riskscore_bar(self, top_riskscore, project_id, output_folder, output_filename):
logger.debug("Inside method plotgraph in drawchart.py.")
y_pos = np.arange(len(project_id))
width = .4
fig, ax = plt.subplots()
graph = ax.bar(y_pos+1, top_riskscore, width, color='#feb308')
ax.set_ylabel('Risk Score')
ax.set_title('Summary')
ax.set_xticks(y_pos + 1)
ax.set_xticklabels(project_id,fontsize=5, rotation=45 )
def autolabel(rects):
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width()/2., 1.001*height,
'%d' % int(height),
ha='center', va='bottom')
autolabel(graph)
pylab.savefig(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', output_folder,output_filename))
The error seems to occur at "fig, ax = plt.subplots()". any ideas on how this can be fixed?
this can be solved by adding plt.switch_backend('agg') below right after you import matplotlib.pyplot as plt. As shown below
import matplotlib.pyplot as plt
plt.switch_backend('agg')
I'm trying to plot a data set (777 x 576) with 3D contours. This appears to be working fine until I try to place the contour under the 3d plot.
from mpl_toolkits.mplot3d import axes3d
from matplotlib import cm, pyplot
import numpy
X,Y = numpy.mgrid[:len(data), :len(data[0])]
fig = pyplot.figure('''figsize=(20, 10), dpi=800''')
ax = fig.gca(projection='3d')
ax.plot_surface(X,
Y,
data,
rstride=100,
cstride=100,
alpha=0.3,
linewidths=(.5,),
antialiased=True,
)
# cset = ax.contourf(X, Y, data, zdir='z', offset=130, cmap=cm.coolwarm)
ax.set_xlim(800, 0)
ax.set_ylim(0, 600)
ax.set_zlim(130, 170)
plt.show()
That is to say that uncommenting the ax.contourf(...) line causes the following exception:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
return self.func(*args)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 276, in resize
self.show()
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 348, in draw
FigureCanvasAgg.draw(self)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_agg.py", line 451, in draw
self.figure.draw(self.renderer)
File "C:\Python27\lib\site-packages\matplotlib\artist.py", line 55, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\figure.py", line 1034, in draw
func(*args)
File "C:\Python27\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 248, in draw
for col in self.collections]
File "C:\Python27\lib\site-packages\mpl_toolkits\mplot3d\art3d.py", line 456, in do_3d_projection
cedge = cedge.repeat(len(xyzlist), axis=0)
ValueError: array is too big.
In case this means anything:
len(cedge) == 35656
len(xyzlist) == 8914
35656 * 8914 = 317837584
Is there something I need to set to accommodate my data set?
I'm getting some memory problems from plotting images in a loop. How do I delete the old ones?
Error:
Traceback (most recent call last):
File "C:\Users\Alex\Dropbox\code stuff\solarsystem.py", line 69, in <module>
fig = plt.figure()
File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 343, in figure
**kwargs)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 79, in new_figure_manager
return new_figure_manager_given_figure(num, figure)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 106, in new_figure_manager_given_figure
canvas = FigureCanvasTkAgg(figure, master=window)
File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 225, in __init__
master=self._tkcanvas, width=w, height=h)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 3306, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 3262, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
TclError: not enough free memory for image buffer
Script:
count = 0
xy = bodies[0][2]
x = [[a[0] for a in bodies[0][2]]]
y = [[a[1] for a in bodies[0][2]]]
z = [[a[2] for a in bodies[0][2]]]
for i in range(1,nbodies):
x.append([a[0] for a in bodies[i][2]])
y.append([a[1] for a in bodies[i][2]])
z.append([a[2] for a in bodies[i][2]])
for j in range(0,len(bodies[0][2])-1,10):
Xc = [[x[0][j]]]
Yc = [[y[0][j]]]
Zc = [[z[0][j]]]
for k in range(1,nbodies):
Xc.append([x[k][j]])
Yc.append([y[k][j]])
Zc.append([z[k][j]])
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for l in range(len(Xc)):
ax.scatter( Xc[l], Yc[l], Zc[l], c=(i/nbodies,i/nbodies,i/nbodies))
ax.axis([-400, 400, -400, 400])
ax.set_zlim(-400, 400)
pylab.savefig('images/img'+str(count))
pylab.clf()
count += 1
percent = (j/(len(bodies[0][2])-1.))*100
if percent % 10 ==0:
print percent
If you're generating a number of pictures, you need to not only call the
plt.clf()
function between figures, but also the
plt.close()
function between pictures (i.e. after the for j in range(0,len(bodies[0][2])-1,10):
loop completes)
You can delete the fig instance (when you're done with it) using
del fig
and you can delete the files with os.unlink
os.unlink('images/img'+str(count))