Renderer problems using Matplotlib from within a script - python

I've narrowed down to this call:
fig.canvas.tostring_argb() #fig=matplotlib.pyplot.figure()
this function raises an AttributeError when I run the code as a python script.
AttributeError: 'FigureCanvasGTKAgg' object has no attribute 'renderer'
However, this code works properly if run in the ipython --pylab command line.
As far as I can tell from the documentation, the Agg renderer should work OK.
The context is that I'm trying to make a movie from figures, without saving the frames
to disk; as per this question. I'm using the approach that streams the pixel arrays
to ffmpeg (running as a separate process) to do this, I need the argb array of values from the frame.
Is there some configuration setting I can make to get matplotlib to work correctly from within a script?
Edit
Tried use('Agg') as per a comment; still fails; this is a minimal working example.
[dave#dave tools]$ python -c "import matplotlib; matplotlib.use('Agg'); import matplotlib.pyplot; fig=matplotlib.pyplot.figure(); fig.canvas.tostring_argb()"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 416, in tostring_argb
return self.renderer.tostring_argb()
AttributeError: FigureCanvasAgg instance has no attribute 'renderer'

I suspect that you have missed out the call to:
fig.canvas.draw()
before
fig.canvas.tostring_argb()
as
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot
fig=matplotlib.pyplot.figure()
fig.canvas.tostring_argb()
fails for me, but
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot
fig=matplotlib.pyplot.figure()
fig.canvas.draw()
fig.canvas.tostring_argb()
works.

I ended up installing and using the WXAgg backend; the Agg,and default GTKAgg, didn't work for me.

Related

Matplotlib can't find documented function set_cmap

I have the following code:
import matplotlib.pyplot as plt
plt.cm.set_cmap("Blues")
This gives me an error:
Traceback (most recent call last):
File ".\lorenz_explorer.py", line 12, in <module>
plt.cm.set_cmap("Blues")
AttributeError: module 'matplotlib.cm' has no attribute 'set_cmap'
My matplotlib version is 3.3.1, and the function certainly exists in the documentation for 3.3.1: Link
Then am I doing something wrong or is this a bug? Do I need to import matplotlib.cm separately or something along those lines?
As the documentation link you provide shows, the name of the function is matplotlib.pyplot.set_cmap, not matplotlib.pyplot.cm.set_cmap. So you can call it with plt.set_cmap("Blues").
In other words, the function is not part of the cm library, which is somewhat counter-intuitive.

How do I get rid of attribute error in matplotlib animation

I want to turn a series of matplotlib figures into an animation. However, whatever I do, I always receive error. I use Enthought Canopy 1.6.2 and Python 2.7.13 on Windows 10.
I have tried using videofig package. While it was good, I could not manage to save the mp4 file. Also, I believe using the source directly, i.e., matplotlib animation package would be more versatile for future uses. I checked a few answers, including 1, 2 and 3, yet none of them solved my problem.
The function I call is structured as follows.
def some_plotter(self, path, start_value, image_array)
some_unrelated_fig_functions()
im=plt.savefig(path, animated=True)
image_array.append([im])
plt.close("all")
The main code is as follows:
import matplotlib.animation as animation
image_array=[]
while(something):
some_obj.some_plotter(path, start_value, image_array)
fig = plt.figure()
ani = animation.ArtistAnimation(fig, image_array, interval=50, blit=True, repeat_delay=1000)
I receive the following error:
Traceback (most recent call last):
File "C:\Users\kocac\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\cbook__init__.py", line 387, in process
proxy(*args, **kwargs)
File "C:\Users\kocac\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\cbook__init__.py", line 227, in call
return mtd(*args, **kwargs)
File "C:\Users\kocac\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\animation.py", line 1026, in _start
self._init_draw()
File "C:\Users\kocac\AppData\Local\Enthought\Canopy\edm\envs\User\lib\site-packages\matplotlib\animation.py", line 1557, in _init_draw
artist.set_visible(False)
AttributeError: 'NoneType' object has no attribute 'set_visible'
I had more similar lines to this, yet updating Matplotlib, following the suggestion at 3 reduced the error lines to 4. Yet I cannot proceed any longer. Note that saved images are perfectly fine so I am probably not doing anything wrong in the image creation.
How can I get rid of these errors? Where am I going wrong?

I cannot call show() after close() with matplotlib in python

I'm new to Python (I used MATLAB before), and I find that I cannot call show() after close some figures by close(). My goal is closing figures freely and then show the rest plots at last. Could anyone help me? Thank you.
My system: Python 3.6 on Windows 10. The matplotlib version is 2.2.2. I run my code through Eclipse.
Here is the code:
# Original code
import matplotlib.pyplot as plt
figA = plt.figure('aa')
figB = plt.figure('bb')
plt.close('aa')
plt.plot([2,3],[1,1],color='green')
plt.show()
When I run it, I get the following error in the Eclipse console.
Traceback (most recent call last):
File "D:\a project for testing dionysus\test_pythonPractice.py", line 26, in
plt.show()
File "C:\Users\hanlin\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\pyplot.py", line 253, in show
return _show(*args, **kw)
File "C:\Users\hanlin\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\backend_bases.py", line 208, in show
cls.mainloop()
File "C:\Users\hanlin\AppData\Local\Programs\Python\Python36\lib\site-packages\matplotlib\backends_backend_tk.py", line 1073, in mainloop
Tk.mainloop()
File "C:\Users\hanlin\AppData\Local\Programs\Python\Python36\lib\tkinter__init__.py", line 557, in mainloop
_default_root.tk.mainloop(n)
AttributeError: 'NoneType' object has no attribute 'tk'
However, if I change the code to either of the following two versions, there is no error.
# Revised ver.1
import matplotlib.pyplot as plt
figA = plt.figure('aa')
figB = plt.figure('bb')
plt.close('bb')
plt.plot([2,3],[1,1],color='green')
plt.show()
or
# Revised ver.2
import matplotlib.pyplot as plt
figA = plt.figure('aa')
figB = plt.figure('bb')
plt.close('aa')
plt.plot([2,3],[1,1],color='green')
plt.show(block=False)
plt.pause(3)
From revised ver.1, my guess is that close() only works on the last added figure. If we remove the previous figure, there will be an "empty" element in the list recording those figures. But this assumption violates the revised ver.2... Does anyone know why and how to solve this problem? Thank you.
Thanks to #Mr.T and #DavidG, I figure it out. Now the code becomes
# Revised original code
import matplotlib
matplotlib.use("Qt5Agg")
import matplotlib.pyplot as plt
figA = plt.figure('aa')
figB = plt.figure('bb')
plt.close('aa')
plt.plot([2,3],[1,1],color='green')
plt.show()
The culprit is the backend (default: "TkAgg"), and I set it as "Qt5Agg" now. I install the package pyqt5 by
pip install pyqt5==5.10.1
Note that the pyqt5 version needs to be 5.10.1. The latest one (5.11.2) would cause another error. For details, please read the webpage.

Can't use matplotlib.use('Agg'), graphs always show on the screen

I'm studying matplotlib and don't know how to just save the graph and not print it on the screen.
So I've done some research on the Internet, many answers said the solution is matplotlib.use('Agg'). And it must be before importing matplotlib.pyplot or pylab.
Then when I added it in the first line of my script, it doesn't work at all.
import matplotlib
matplotlib.use('Agg')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
E:\Program Files\Anaconda3\lib\site-packages\matplotlib\__init__.py:1401: UserWarning: This call to matplotlib.use() has no effect
because the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
warnings.warn(_use_error_msg)
I use Anaconda Spyder, so I restarted kernel and ran my script again, I got same wrong information.
Then I restarted kernel again and directly typed the following code in the console:
In[1]: import matplotlib as mpl
In[2]: mpl.use('Agg')
E:\Program Files\Anaconda3\lib\site-packages\matplotlib\__init__.py:1401: UserWarning: This call to matplotlib.use() has no effect
because the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.
warnings.warn(_use_error_msg)
Also, if I delete 'plt.show()' at the end of script or add 'plt.ioff()', the graph will always print on the screen.
Thanks for everyone's answer. Now I have two solutions:
just use plt.close() , this will not change the backend and the figure doesn't show up.
use plt.switch_backend('Agg'), this will switch the backend to 'agg' and no figure printed on the screen.
You can try to switch the backend. Apparently Spyder loads matplotlib before you do, and use has no effect. This may be helpful:
How to switch backends in matplotlib / Python
The answer to your original question is simple.
If you don't want to show the graph on screen, just don't use plt.show()
So what you've gotta do is simply:
import matplotlib.pylab as plt
plt.plot(x,y) #whatever the x, y data be
#plt.show() """Important: either comment this line or delete it"""
plt.savefig('path/where/you/want/to/save/filename.ext')
#'filename' is either a new file or an already existing one which will get overwritten at the time of execution. 'ext' can be any valid image format including jpg, png, pdf, etc.
plt.plot(x,y)
plt.savefig('path/figure_filename.jpg',dpi=300)

pyqtgraph: calling PlotDataItem.setData gives TypeError: PySide.QtCore.QPointF.__add__ called with wrong argument types

Background
I am using pyqtgraph to make an interactive program that plots and analyzes some data.
Versions of relevant things:
PySide version 1.2.1
from PySide import QtGui, QtCore
pyqtgraph version 0.9.10 (latest at the moment):
from <my own package>.external import pyqtgraph
On Ubuntu 14.04.3 LTS
Python 2.7.6
Code Structure
self.w.dotPlot is a pyqtgraph.PlotWidget object
I draw a box by doing this:
self.timeBox = self.w.dotPlot.plot(x=self.baseTimeBoxX,y=self.baseTimeBoxY,...)
where:
from numpy import r_
self.baseTimeBoxX = r_[0.0,0.0,100.0,100.0,0.0]
self.baseTimeBoxY = r_[-1.0,1.0,1.0,-1.0,-1.0]
self.w.timeBox is thus an instance of pyqtgraph.graphicsItems.PlotDataItem.PlotDataItem
When the user clicks on the plot, I want to move the box in the X direction only. To do this, I figure out the clickedXCoord, add this to self.baseTimeBoxX, and now want to update self.w.timeBox to use these x coordinates. To do so, I call
self.w.timeBox.setData(
x=(clickedXCoord+self.baseTimeBoxX),
y=self.baseTimeBoxY
)
The Problem
Here is the traceback that I get:
Traceback (most recent call last):
File "doesntMatter.py", line <whatever>, in _moveTimeBox
self.w.timeBox.setData(x=(clickedXCoord+self.baseTimeBoxX),y=self.baseTimeBoxY)
TypeError: 'PySide.QtCore.QPointF.__add__' called with wrong argument types:
PySide.QtCore.QPointF.__add__(numpy.ndarray)
Supported signatures:
PySide.QtCore.QPointF.__add__(PySide.QtCore.QPointF)
Things I have tried:
Instead of changing the data in the existing PlotDataItem using self.w.timeBox.setData, I tried just creating a whole new one:
self.w.timeBox = self.w.dotPlot.plot(
x=(clickedXCoord+self.baseTimeBoxX),
y=self.baseTimeBoxY
)
I got basically the same error

Categories