Why matplotlib does not plot? - python

I started to learn MatPlotLib using this tutorial for beginners. Here is the first example.
from pylab import *
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
If I write these 3 lines into my python file and execute it in the command line (by typing python file_name.py), nothing happens. No error message, no plot.
Does anybody know why I do not see the plot?
ADDED
Of course I need to use show. But even if I add the following 3 lines:
plot(X,C)
plot(X,S)
show()
it still does no generate anything.
ADDED
Here are the lines that I use now:
import pylab as p
C = [1,2,3,4]
S = [10, 20, 30, 10]
p.plot(C,S)
p.show()
I still have the same result (nothing).

It could be a problem with the backend.
What is the output of
python -c 'import matplotlib; import matplotlib.pyplot; print(matplotlib.backends.backend)'?
If it is the 'agg' backend, what you see is the expected behaviour as it is a non-interactive backend that does not show anything to the screen, but work with plt.savefig(...).
You should switch to, e.g., TkAgg or Qt4Agg to be able to use show. You can do it in the matplotlib.rc file.
#shashank: I run matplotlib both on 12.04 and 12.10 without problems. In both cases I use the Qt4Agg backend. If you don't have the matplotlibrc set, the default backend is used.
I'm sure that for Precise matplotlib repo was built with TkAgg. If the Quantal version has been built with e.g. Agg, then that would explain the difference

You need to call the function:
show()
to be more exact:
pylab.show()
and even better don't use:
from pylab import *
rather do:
import pylab as p:
and then:
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
p.plot(C,S)
p.show()

Try adding. I use Jupyter and this worked for me.
%matplotlib inline

Related

Plot matplotlib by running python file

So there was this thread talking about why matplotlib does not show when executing
python myfile.py
The most popular answer was about resetting matplotlibrc file. What would need to be reset in this file?
Also, some suggest to include matplotlib.use('TkAgg') in the import. Below is my python file:
#myfile.py
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
def dyn_draw():
x = np.linspace(0, 6 * np.pi, 100)
y = np.sin(x)
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma
for phase in np.linspace(0, 10 * np.pi, 500):
line1.set_ydata(np.sin(x + phase))
fig.canvas.draw()
fig.canvas.flush_events()
if __name__ == "__main__":
dyn_draw()
Running that with python myfile.py, I get the following error:
ImportError: Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running
Another thread here discussed this error. But the solution still does not work (i.e. restarting the kernel).
How to plot this particular python code with the python command?
You are trying to run matplotlib interatively in a non-interactive environment. The code compiles, but errors at run-time because you running a script.
Have you tried running this in Google Colab? The resource provides free (to a certain point) GPU usage and block coding for interactive visualizations.
Best of luck :)

Pycharm numpy module has no attribute 'py'

Just getting into programming by going through a load of beginner projects. I started one to plot sine and cosine curves, and the code they gave was:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 4*np.py, 0.1)
y = np.sin(x)
plt.plot(x, y)
plt.show()
Every time I try and run the code, it gives the error:
Traceback (most recent call last):
File "C:/Users/Alex/PycharmProjects/projects2/sin2.py", line 5, in <module>
x = np.arange(0, 4*np.py, 0.1)
File "C:\Users\Alex\anaconda3\envs\projects2\lib\site-packages\numpy\__init__.py", line 220, in __getattr__
"{!r}".format(__name__, attr))
AttributeError: module 'numpy' has no attribute 'py'
I've reinstalled Python, pycharm, and numpy to no avail. I believe I'm properly using the anaconda interpreter and I see numpy is properly installed on it. I'm not sure what else I should try, so any suggestions would help. Maybe I should try another IDE? I do like Pycharm so far but I have seen other people with similar issues using Pycharm, so any suggestions there would also be welcome.
I think you are trying to get np.pi
The constant 3.1415926535897932384626433...
If you change it in your code:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 4 * np.pi, 0.1)
y = np.sin(x)
plt.plot(x, y)
plt.show()
It properly runs
I not very familiar with numpy, but I looked through the docs and couldn't find anything for py being part of numpy. Maybe I didn't look hard enough, but it could have been replaced with an update? Also, you could try changing it to "np.py()" with parentheses because it could just be a function instead (however that is probably not likely assuming you got this from a prebuilt project).
I don't know, why are you using 4*np.py, I have seen the documentation of NumPy and it has no such attribute as py. You can try following:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 10, 0.1)
y = np.sin(x)
plt.plot(x, y)
plt.title('sine wave') # To give a title
plt.xlabel('Time') # To give a x-label
plt.ylabel('Y-values') # To give a y-label
plt.grid(True, which='both') # Turns Grid to True
plt.axhline(y=0, color='k') # Draw a black horizontal line at y=0
plt.show()
Output:

How to manipulate figures while a script is running in Python?

Introduction
As I am coming from matlab, I am used to an interactive interface where a script can update figures while it is running. During the processing each figure can be re-sized or even closed. This probably means that each figure is running in its own thread which is obviously not the case with matplotlib.
IPython can imitate the Matlab behavior using the magic command %pylab or %matplotlib which does something that I don't understand yet and which is the very point of my question.
My goal is then to allow standalone Python scripts to work as Matlab does (or as IPython with %matplotlib does). In other words, I would like this script to be executed from the command line. I am expecting a new figure that pop-up every 3 seconds. During the execution I would be able to zoom, resize or even close the figure.
#!/usr/bin/python
import matplotlib.pyplot as plt
import time
def do_some_work():
time.sleep(3)
for i in range(10):
plt.plot([1,2,3,4])
plt.show() # this is way too boilerplate, I'd like to avoid it too.
do_some_work()
What alternative to %matplotlib I can use to manipulate figures while a script is running in Python (not IPython)?
What solutions I've already investigated?
I currently found 3 way to get a plot show.
1. %pylab / %matplotlib
As tom said, the use of %pylab should be avoided to prevent the namespace to be polluted.
>>> %pylab
>>> plot([1,2,3,4])
This solution is sweet, the plot is non-blocking, there is no need for an additionnal show(), I can still add a grid with grid() afterwards and I can close, resize or zoom on my figure with no additional issues.
Unfortunately the %matplotlib command is only available on IPython.
2. from pylab import * or from matplotlib.pyplot import plt
>>> from pylab import *
>>> plot([1,2,3,4])
Things are quite different here. I need to add the command show() to display my figure which is blocking. I cannot do anything but closing the figure to execute the next command such as grid() which will have no effect since the figure is now closed...
** 3. from pylab import * or from matplotlib.pyplot import plt + ion()**
Some suggestions recommend to use the ion() command as follow:
>>> from pylab import *
>>> ion()
>>> plot([1,2,3,4])
>>> draw()
>>> pause(0.0001)
Unfortunately, even if the plot shows, I cannot close the figure manually. I will need to execute close() on the terminal which is not very convenient. Moreover the need for two additional commands such as draw(); pause(0.0001) is not what I am expecting.
Summary
With %pylab, everything is wonderful, but I cannot use it outside of IPython
With from pylab import * followed by a plot, I get a blocking behavior and all the power of IPython is wasted.
from pylab import * followed by ion offers a nice alternative to the previous one, but I have to use the weird pause(0.0001) command that leads to a window that I cannot close manually (I know that the pause is not needed with some backends. I am using WxAgg which is the only one that works well on Cygwin x64.
This question advices to use matplotlib.interactive(True). Unfortunately it does not work and gives the same behavior as ion() does.
Change your do_some_work function to the following and it should work.
def do_some_work():
plt.pause(3)
For interactive backends plt.pause(3) starts the event loop for 3 seconds so that it can process your resize events. Note that the documentation says that it is an experimental function and that for complex animations you should use the animation module.
The, %pylab and %matplotlib magic commands also start an event loop, which is why user interaction with the plots is possible. Alternatively, you can start the event loop with %gui wx, and turn it off with %gui. You can use the IPython.lib.guisupport.is_event_loop_running_wx() function to test if it is running.
The reason for using ion() or ioff() is very well explained in the 'What is interactive mode' page. In principle, user interaction is possible without IPython. However, I could not get the interactive-example from that page to work with the Qt4Agg backend, only with the MacOSX backend (on my Mac). I didn't try with the WX backend.
Edit
I did manage to get the interactive-example to work with the Qt4Agg backend by using PyQt4 instead of PySide (so by setting backend.qt4 : PyQt4 in my ~/.config/matplotlibrc file). I think the example doesn't work with all backends. I submitted an issue here.
Edit 2
I'm afraid I can't think of a way of manipulating the figure while a long calculation is running, without using threads. As you mentioned: Matplotlib doesn't start a thread, and neither does IPython. The %pylab and %matplotlib commands alternate between processing commands from the read-eval-print loop and letting the GUI processing events for a short time. They do this sequentially.
In fact, I'm unable to reproduce your behavior, even with the %matplotlib or %pylab magic. (Just to be clear: in ipython I first call %matplotlib and then %run yourscript.py). The %matplotlib magic puts Matplotlib in interactive-mode, which makes the plt.show() call non-blocking so that the do_some_work function is executed immediately. However, during the time.sleep(3) call, the figure is unresponsive (this becomes even more apparent if I increase the sleeping period). I don't understand how this can work at your end.
Unless I'm wrong you'll have to break up your calculation in smaller parts and use plt.pause (or even better, the animation module) to update the figures.
My advice would be to keep using IPython, since it manages the GUI event loop for you (that's what pylab/pylot does).
I tried interactive plotting in a normal interpreter and it worked the way it is expected, even without calling ion() (Debian unstable, Python 3.4.3+, Matplotlib 1.4.2-3.1). If I recall it right, it's a fairly new feature in Matplotlib.
Alternatively, you can also use Matplotlib's animation capabilities to update a plot periodically:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
plt.ion()
tt = np.linspace(0, 1, 200)
freq = 1 # parameter for sine
t0 = time.time() # for measuring ellapsed time
fig, ax = plt.subplots()
def draw_func(i):
""" This function gets called repeated times """
global freq # needed because freq is changed in this function
xx = np.sin(2*np.pi*freq*tt)/freq
ax.set_title("Passed Time: %.1f s, " % (time.time()-t0) +
"Parameter i=%d" % i)
ax.plot(tt, xx, label="$f=%d$ Hz" % freq)
ax.legend()
freq += 1
# call draw_func every 3 seconds 1 + 4 times (first time is initialization):
ani = animation.FuncAnimation(fig, draw_func, np.arange(4), interval=3000,
repeat=False)
# plt.show()
Checkout matplotlib.animation.FuncAnimation for details. You'll find further examples in the examples section.

Hold is not working for pyplot

I have a problem using pyplot. I am new to Python so sorry if I am doing some obvious mistake.
After I have plotted something using pyplot it shows the graph, but when I then try and add e.g. ylabel it will not update the current graph. It results in a new graph with only the ylabel, not previously entered information. So to me it seems to be a problem with recognizing the current graph/axis, but the ishold delivers a True statement.
My setup is Python 2.7 in Python(x,y). The problem occurs both in the Spyder IDE and the IPython Qt Console. It does however not occur in the regular IPython console (which, by constrast, is not interactive, but everything is included when using show(). When I turn off interactive in Spyder/Qt console it does not show anything after using the show() command).
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
Out[2]: [<matplotlib.lines.Line2D at 0x78ca370>]

plt.ylabel('test')
Out[3]: <matplotlib.text.Text at 0x5bd5990>

plt.ishold()
Out[4]: True
matplotlib.get_backend()
Out[6]: 'module://IPython.kernel.zmq.pylab.backend_inline'
Hope any of you have some input. Thanks.
This is one of the things were InlineBackend have to behave differently from other backend or you would have sort of a memory leak. You have to keep explicit handle to matplotlib figure and/or set close_figure to False in config. Usually pyplot is a compatibility layer for matlab for convenience, try to learn to do using the Object Oriented way.
fig,ax = subplots()
ax.plot(range(4))
ax.set_ylabel('my label')
...

Use pylab to plot image returned from Scipy

I'm working to migrate from MatLab to python in Sage.
So I use these commands and I faced this error in Sage:
from scipy import misc
l = misc.lena();
import pylab as pl
pl.imshow(l)
The Error or message (i don't know) is:
matplotlib.image.AxesImage object at 0xb80198c
And it doesn't show any image
It's not an error, just print the object that method returned.
There are two ways to show the figure:
Add pl.show() after calling pl.imshow(l)
Use ipython --pylab to open your python shell,
That is an object being returned from pylab after using the "imshow" command. That is the location of the Axes image object.
documentation:
http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.imshow
Looks like it says it displays the object to the current axes. If you havent already created a plot I imagine you wont see anything
Simple google search suggests this might be what you are looking for
http://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.lena.html
from scipy import misc
l = misc.lena();
import pylab as pl
pl.imshow(l)
####use this
pl.show()

Categories