how to draw empty plot on jupyter notebook instead address? [duplicate] - python

This question already has answers here:
How to make IPython notebook matplotlib plot inline
(11 answers)
Closed 4 years ago.
import matplotlib.pyplot as plt
%matplotlib inline
fig=plt.figure()
plt.show()
Output is:
matplotlib.figure.Figure at 0x536ea70
I want to see empty plot and i was going through a pycon tutorial the same code produced a empty plot.

IPython will not generate any output for figures that do not contain an axes.
If you add an axes to your figure, the figure will show fine.
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.show()
or
%matplotlib inline
import matplotlib.pyplot as plt
plt.gca()
plt.show()
If you then remove the axes, it will again show the returned python string again.
The solution to show a completely empty figure with the inline backend is hence to add an axes but then turn it invisible.
%matplotlib inline
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_visible(False)
plt.show()

Related

Printing cursor coordinates in a matplotib figure in a Jupyter notebook: the smooth way

I want to display the coordinates of my cursor in an image displayed with matplotlib within a Jupyter notebook.
I am using the %matplotlib notebook magic as per this question.
While this provides a nice answer for a static figure, this results in a huge amount of flickering and bugs (the figure sometimes not showing) when used in an interactive setting where the figure is constantly redrawn during slicing. For example,
%matplotlib notebook
from ipywidgets import interact
import matplotlib.pyplot as plt
import numpy as np
vol = np.random.uniform(size=(16, 16, 16))
#interact(z=(0, 15))
def show(z):
plt.imshow(vol[z])
plt.show()
Without %matplotlib notebook, the figure is updating without any flicker, but does not show the cursor coordinates. With the magic, the coordinates are displayed, but the flickering is unbearable.
Is there a way to have pixel coordinates without flickering in that simple situation?
The problem is the use of plt.show(), which will replace the figure. Instead you probably want to update the existing figure.
%matplotlib notebook
from ipywidgets import interact
import matplotlib.pyplot as plt
import numpy as np
vol = np.random.uniform(size=(16, 16, 16))
fig, ax = plt.subplots()
im = ax.imshow(vol[0])
#interact(z=(0, 15))
def show(z):
im.set_array(vol[z])
im.set_clim(vol[z].min(), vol[z].max())
fig.canvas.draw_idle()
Note the the above provides the same functionality as the code in the question, i.e. each array is normalized individually. However, you might decide to set the color normalization only once such that all arrays share the same color limits.
%matplotlib notebook
from ipywidgets import interact
import matplotlib.pyplot as plt
import numpy as np
vol = np.random.uniform(size=(16, 16, 16))
fig, ax = plt.subplots()
im = ax.imshow(vol[0], vmin=vol.min(), vmax=vol.max())
fig.colorbar(im)
#interact(z=(0, 15))
def show(z):
im.set_array(vol[z])
fig.canvas.draw_idle()

How do you update inline images in Ipython?

Edit: My question is not in regards to an "animation" per se. My question here, is simply about how to continuously show, a new inline image, in a for loop, within an Ipython notebook.
In essence, I would like to show an updated image, at the same location, inline, and have it update within the loop to show. So my code currently looks something like this:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from IPython import display
%matplotlib inline
fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize=(10, 10))
for ii in xrange(10):
im = np.random.randn(100,100)
ax.cla()
ax.imshow(im, interpolation='None')
ax.set_title(ii)
plt.show()
The problem is that this currently just..., well, shows the first image, and then it never changes.
Instead, I would like it to simply show the updated image at each iteration, inline, at the same place. How do I do that? Thanks.
I am not sure that you can do this without animation. Notebooks capture the output of matplotlib to include in the cell once the plotting is over. The animation framework is rather generic and covers anything that is not a static image. matplotlib.animation.FuncAnimation would probably do what you want.
I adapted your code as follows:
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation
f = plt.figure()
ax = f.gca()
im = np.random.randn(100,100)
image = plt.imshow(im, interpolation='None', animated=True)
def function_for_animation(frame_index):
im = np.random.randn(100,100)
image.set_data(im)
ax.set_title(str(frame_index))
return image,
ani = matplotlib.animation.FuncAnimation(f, function_for_animation, interval=200, frames=10, blit=True)
Note: You must restart the notebook for the %matplotlib notebook to take effect and use a backend that supports animation.
EDIT: There is normally a way that is closer to your original question but it errors on my computer. In the example animation_demo there is a plain "for loop" with a plt.pause(0.5) statement that should also work.
You can call figure.canvas.draw() each time you append something new to the figure. This will refresh the plot (from here). Try:
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from IPython import display
from time import sleep
fig = plt.figure()
ax = fig.gca()
fig.show()
for ii in range(10):
im = np.random.randn(100, 100)
plt.imshow(im, interpolation='None')
ax.set_title(ii)
fig.canvas.draw()
sleep(0.1)
I could not test this in an IPython Notebook, however.

Matplotlib didn’t show the plot

I don’t know why my matplotlib didn’t show plots, and no errors too. I thinks I missing something on its installation because when in IPython notebooks an QtIpython using %mayplotlib inline directive have no problems but when running from terminal or script didn’t show anything. Any ideas ??
for example, in QtIPython and Ipython notebook I run
%matplotlib inline
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
ax.plot([1,2,3,4,5,6,7,8,9,0],[2,3,4,5,6,7,8,9,0,11], '-r')
ax.grid()
plt.show()
and the plot shows Ok!
but in a simple script with
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
ax.plot([1,2,3,4,5,6,7,8,9,0],[2,3,4,5,6,7,8,9,0,11], '-r')
ax.grid()
plt.show()
didn’t show anything
If you use matplotlib inline in IPython notebook, the plots are shown automatically. If you plot things in a script you have to put a plt.show() at the end to actually show the figure. In the terminal you can also use plt.ion() to switch on intreactive mode.

How to create a plot in matplotlib without using pyplot

I've been using matplotlib for five months now on a daily basis, and I still find creation of new figures confusing.
Usually I create a figure with 2x2 subplots using, for example, somthing like:
import matplotlib.pyplot as plt
import itertools as it
fig,axes = plt.subplots(2,2)
axit = (ax for ax in it.chain(*axes))
for each of four data series I want to plot:
ax = next(axit)
ax.plot(...)
The question I have now is: how can operate completely independently of pyplot, ie, how can I create a figure, populate it with plots, make style changes, and only tell that figure to appear at the exact moment I want it to appear. Here is what I am having trouble with:
import matplotlib as mpl
gs = gridspec.GridSpec(2,2)
fig = mpl.figure.Figure()
ax1 = fig.add_subplot(gs[0])
ax1.plot([1,2,3])
ax2 = fig.add_subplot(gs[1])
ax2.plot([3,2,1])
After running the above, the only thing that comes to mind would be to use:
plt.draw()
But this does not work. What is missing to make the figure with the plots appear? Also, is
fig = mpl.figure.Figure()
all I have to do to create the figure without pyplot?
This works for me without matplotlib.pyplot
import sys
from PyQt5 import QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas)
from matplotlib.figure import Figure
import numpy as np
fig=Figure()
canvas=FigureCanvas(fig)
ax=canvas.figure.add_subplot(111)
x=np.arange(-5,5,0.1)
y=np.sin(x)
ax.plot(x,y)
canvas.show()
app=QtWidgets.QApplication(sys.argv)
app.exec()
You could attach a suitable backend to your figure manually and then show it:
from matplotlib.backends import backend_qt4agg # e.g.
backend_qt4agg.new_figure_manager_given_figure(1, fig)
fig.show()
... but why not use pyplot?

Changing seaborn style in subplots

I'm trying to change the styles of two plots that are in the same figure:
import numpy as np
from numpy.random import randn
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(15,6))
data = randn(7500);
sns.set_style("whitegrid");
ax1.hist(data, bins=8);
sns.set_style("darkgrid");
ax2.hist(data, bins=8);
This does not work, both plots end up having the "darkgrid" background. I have also trying tinkering with axes_style() with no success.
The way matplotlib Axes work is that the style parameters become a property of the Axes object at the time it is created, not at the time something is drawn onto it. So while it's not possible to make a figure that has different subplot styles using plt.subplots, you can do it with one of the ways where you independently create the Axes:
fig = plt.figure()
with sns.axes_style("whitegrid"):
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
Note also that I'm using a context manager to style the first Axes, so the second Axes will have the default style. It's possible to use sns.set_style before each add_subplot command like you do in the question, but using the context manager to create the non-default plot feels a little bit more Pythonic.

Categories

Resources