Kernel restart when setting x_lim matplotlib - python

I am drawing a scatter plot using Matplotlib on IPython notebook.
When I limit my x axis from 0 to 6e7 I get Kernel restart error.
What shall I do?
Here's the code which I using to limit the x axis:
ax.set_xlim(0, 6e7)
Without the above line everything is working fine.
The reason I want to limit the x axis is that I want to have many plots from different data and able to compare them. Therefore I want my different plots to have same axis.
UPDATE
I just noticed that even if I limit my x axis from 0 to 100, I am getting the same error.
Additional information
Error message: The kernel appears to have died. It will restart automatically.
Code snippet I am using:
The line which I have commented above is causing the problem.
IPython version: 4.0.1
Matplotlib version: 1.5.0

This seems to be due to IPython Notebook limitations. For debugging:
Copy all your relevant code into a file.
Add plt.show() at the end of the file.
Save this file as myfile.py.
Run it from the console: python myfile.py.
See if it works our you get an error message.

Related

Require Jupyter notebook to render matplotlib notebook figure before closing

Introduction and examples.
It is a widely known
best practice to
close matplotlib figures after opening them
to avoid consuming too much memory.
In a standalone Python script, for example,
I might do something like this:
fig, ax = plt.subplots()
ax.plot(x, y1);
plt.show() # stop here and wait for user to finish
plt.close(fig)
Similarly, for a Jupyter notebook
it's a common pattern to create a figure in one cell
and then close it in the next cell.
A minimal example might look something like this,
where each blank line is a new cell:
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y1);
plt.close(fig)
However, this has a distinct disadvantage:
the figure is blank when run with "Kernel" -> "Restart & Run All"
or "Cell" -> "Run All".
That is, the figure doesn't display until all cells finish evaluating,
but the figure doesn't have time to render
since we are using plt.close right afterward.
Here's an example screenshot based on the example above:
This is different from running each cell individually:
as long as I run each cell slowly enough,
I can get each figure to display:
Full Jupyter notebook .ipynb files are available here:
https://github.com/nbeaver/jupyter-figure-rendering-tests
Inadequate workarounds.
The simplest workaround is start from the top
and manually step through each cell,
wait for it to render, and then move onto the next cell.
I don't consider this an acceptable workaround,
as it becomes impractically laborious for large notebooks
and is generally contrary to the purpose of an executable notebook environment.
Another workaround is to simply never call plt.close(fig).
This is not a good option for several reasons:
It results in excess memory usage,
as evidenced by warnings about opening too many figures.
On some machines or resource-constrained environments
this may prevent the notebook execution from completing at all.
Even in environments with abundant memory,
cursor tracking and interactive functionality like zoom or pan
becomes very slow when many figures are open at once.
As mentioned above, in general none of the figures will
display until the final cell has finished executing,
which is undesirable for notebooks
where execution time may be long for certain cells further down.
Another workaround is to use %matplotlib inline
instead of %matplotlib notebook.
This is unsatisfactory also:
The inline mode does not permit interactive inspection of the figure
such as cursor position values or pan and zoom.
This functionality may be desirable or essential for analysis.
The inline and notebook settings cannot in general be toggled on a per-cell basis,
so effectively this is an all-or-nothing setting.
Even if it were possible to toggle between inline and notebook,
I would prefer to only use notebook and then
close the figure in a subsequent cell,
so that I can return to the cell later
and re-run it to get the interactive controls
without needing to edit the cell.
An analogous workaround is to call savefig for each cell with a figure
and then browse the generated images with an external image viewing program.
While this allows limited zooming and panning,
it doesn't give cursor positions
and it's really not comparable to the interactive notebook plots.
Criteria and current workaround.
Here are my requirements:
The effect of "Restart & Run All" must render all figures eventually;
no figures can be left blank.
Use %matplotlib notebook for all cells
so that I can re-run the cell later and inspect the figure interactively.
Allow plt.close(fig) after each cell so that notebook
resources can be conserved.
Essentially, I would like a way to force the kernel
to render the current figure
before proceeding on to plt.close(fig).
My hope is that this is a well-known behavior
and that I've simply missed something.
Here's what I have tried so far that didn't help at all:
plt.show() at the end of a cell or between cells.
fig.show() at the end of a cell or between cells.
plt.ioff() at the end of a cell or between cells.
time.sleep(1) at the end of a cell or between cells.
plt.pause(1) at the end of a cell or between cells.
fig.canvas.draw_idle() at the end of a cell or between cells.
Doing from IPython.display import display and then display(fig)
at the end of a cell or between cells.
calling plt.close('all') at end of notebook instead of between each cell.
Currently, the best I've been able to do
is call fig.canvas.draw() in a separate cell
between the figure and the cell with plt.close(fig).
Using the example above, here's what this looks like:
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y1);
fig.canvas.draw()
plt.close(fig)
This works reliably in smaller notebooks,
and for a while I thought this had solved the problem.
However, this doesn't always work;
particularly in large notebooks with many figures,
some of them still come out blank,
suggesting that fig.canvas.draw() adds some delay
but is not always sufficient,
perhaps due to a race condition.
Since fig.canvas.draw() is not a documented method
for making Jupyter notebooks render the current figure,
I would hesitate to describe this as a bug,
although it seems to be the closely related to this matplotlib issue,
which ultimately seems to be a Jupyter bug:
The simplest work around may be to put the input() call in the next cell or to add plt.gcf().canvas.draw() above the input call. This will still result in "dead" figures (which may not have caught up to the hi-dpi settings of your browser), but they will at least show.
I've observed this behavior in many combinations of matplotlib and Jupyter,
including matplotlib version 2.1.1 and 3.5.1
and Jupyter version 4.4.0 and 6.4.8.
I've also observed it in both Google Chrome 99.0.4844.51 and Firefox 97.0.2
and on both Windows 10 and Ubuntu 18.04.6.
Related questions (not duplicates):
Programmatically Stop Interaction for specific Figure in Jupyter notebook
Specify where in output matplotlib figures are rendered in jupyter using figure handles
Get Jupyter notebook to display matplotlib figures in real-time
Force matplotlib to fully render plots in an IPython/Jupyter notebook cell before advancing to next cell

Simple Python animation using pause command not working

I wanted to create a simple animation using plt.pause() command in python. So I tried the first example from this page. If you go there, it shows you a nice animation of a graph growing smoothly. I copy-paste it below
from matplotlib import pyplot as plt
x = []
y = []
for i in range(100):
x.append(i)
y.append(i)
# Mention x and y limits to define their range
plt.xlim(0, 100)
plt.ylim(0, 100)
# Ploting graph
plt.plot(x, y, color = 'green')
plt.pause(0.01)
plt.show()
However, it is giving me 100 different plots with an incremental increase until it completes the range. I think the problem is with figures appearing without waiting for the plt.show() command? Help me. I am using Jupiter 6.0.3 and sypder 4.1.3
Without the .show() command the plot will disappear at the completion of the code. however the animation should still be visible as it is created by the .plot() command.
I am not able to reproduce your problem using Python 3.9.7.
You can always try running the script outside of the IDE using python pathtoscript and see if that resolves the issue.
To build on #Regretful's answer, if you're running in a Jupyter notebook, use %matplotlib qt or some other non-inline backend to get the usual pop-up window, rather than static images.
No idea for Spyder, though!

Matplotlib GUI showing even though I never called plt.show()

I am using the following functions in order...
- plt.figure()
- plt.plot()
- plt.ylim
- plt.xticks()
- figure = plt.gcf()
- figure.set_size_inches()
- plt.savefig()
I just want to save the figure as png, which I've been doing successfully. But the GUI keeps showing up and I am going to generate a bunch of graphs in one script, I don't want the GUI popping up every time one is created and slow my run time.
Does anyone know why it is showing up still?
If you are using a Jupyter Notebook, there are a number of potential solutions posted here.
To summarize, try this to disable inline output from Matplotlib:
import matplotlib as plt
plt.ioff()
Or put this at the start of a cell to prevent it from creating output:
%%capture

Matplotlib and Jupyter notebook multiple interactive plots

I am facing the following problem: I need two interactive plots to work at the same time on Jupyter, however they are interfering. When I rotate the cell of the first, the second plot stops being interactive and becomes "inline". Other times one of the plots looks like this:
The expected result was something like this
I imagine the problem is in the implementation I made. As you can see below, I use plt.something to put things in the figure (both for plot 1 and plot 2).
I'm using the %matplotlib notebook environment and tried to implement using fig1, ax1 = plt.subplots(). I would like to know if it is possible to do this type of implementation, where there is no conflict between plots? Maybe I am using matplotlib badly, so I would like some suggestions.

plt.show() not showing data instead holding it for next plot (spyder)

I have been using the same setup for quite some time now but suddenly I am no longer allowed to plot more than one graph in a program.
Usually I can plot multiple plots after each other and let the program run through it. It executes the next lines of code after closing the first window. However, recently the first plot is not shown but instead the data is added to the last plot.
I have included a sample code which used to give me two plots but now only one.
import matplotlib.pyplot as plt
import numpy as np
random_num = np.random.randint(0,5,10)
random_num_2 = np.random.randint(0,100,10)
plt.plot(random_num, 'ko')
plt.show()
plt.plot(random_num_2, 'g*')
plt.show()
The first image shows the output from my program. But I would like to have them separated into two plots like Figure 2 and 3 show.
Maybe I should add that I am using Python 3.6 with Spyder 3.2.4. The graphics option is set to display it in Qt5 even though I tried all settings and only 'Inline' shows me the results the way I want it.
Sorry if this is a very simple question. I have tried googling but I only come up with questions about my topic where the way mine works would be the solution not the problem.
#TheresaOtt. I would suggest you create a new figure instance (plt.figure()) for each plot and use only once at the end the plt.show() command.

Categories

Resources