I have some plotting functions that are called in a jupyter notebook. The plotting functions include the calls
plt.figure()
and
plt.show()
However, the notebooks add annotations to the plot after the fact. The annotations work properly with
%matplotlib nbagg
but not
%matplotlib inline
which creates a new figure instead of annotating the old one (edit: this is the same behaviour as running a script in terminal). It seems that there's a scoping issue that nbagg circumvents and that inline does not. See below for a minimal reproducible example.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
def plotter():
plt.figure()
x = np.arange(-3,3,0.1)
y = np.exp(-x*x)
plt.scatter(x,y)
plt.show()
plotter()
plt.text(0, 0.5, 'gaus', horizontalalignment='center')
plt.show()
Question: is there a way I can get this to work in inline mode, e.g., by getting the most recently shown figure? I'd rather not edit the back-end plotting functions, which are not my own.
Related
I have written a small library, whose functions generate plots using this structure:
from matplotlib import pyplot as plt, rcParams, rc_context
with rc_context():
print(f'Figure backend {plt.get_backend()}')
x = [1,2,3,4,5]
y = [1,2,3,4,5]
fig, ax = plt.subplots()
ax.scatter(x,y)
plt.show()
plt.close(fig)
I would like this library to be compatible with jupyter notebooks but I am having issues with the backends.
For example: In "qt" backends the plot window is closed inmediatly and in "nbAgg" backends the plot is deleted. This code reproduces the issue.
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt, rcParams, rc_context
%matplotlib notebook
with rc_context():
ts = pd.Series(np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000))
ts = ts.cumsum()
ts.plot()
plt.close()
One solution is removing the plt.close(fig) but that would leave the figures opened.
Another option is adding some criteria to keep/close the figures depending on the backend, but from what I have seen the nomenclature changes from one OS to another, or if running from a notebook. The latter option is not easy though.
I wonder if anyone would please share their experience to keep the matplotlib figures in notebooks.
I am trying to plot multiple bars on the same plot on my jupyter notebook. However, due to some reason, it does not work on the notebook,but it works on a normal python editor. Here is the code that I have used.
import matplotlib.pyplot as plt
plt.bar(['A','B','C'],[72,73,88])
plt.bar(['A','B','C'],[98,77,98])
plt.show()
Any help will be highly appreciated.
(Edit)
I am looking for somthing like this on my jupyter notebook.
I presume you want to have both bar plots side by side. So here you go:
import matplotlib.pyplot as plt
fig,axs = plt.subplots(1,2)
axs[0].bar(['A','B','C'],[72,73,88])
axs[1].bar(['A','B','C'],[98,77,98])
plt.show()
I am able to get an interactive graph in Google colab with the code:
!pip install mpld3
%matplotlib notebook
mpld3.enable_notebook()
df.plot(x = 'Time', y = 'Data')
but the plot is really small.
In R you can click on the graph and it will reopen in the new window. Is there a similar method to do this with colab? Thanks.
google-colaboratory does not provide any native data visualization, but it does support a variety of third-party visualization packages (matplotlib, altair, bokeh, plotly, etc.) You should look in the documentation of the library you are using to see how to adjust the size of figures.
In your example, you appear to be using pandas matplotlib plotting API. As the documentation mentions, you can adjust plot sizes with the figsize argument:
df.plot(x='Time', y='Data', figsize=(16, 10))
mpld3 is an interactive module for matplotlib.
You can understand its working here.
A simplifies answer to the same could be
import matplotlib.pyplot as plt
import mpld3
from mpld3 import plugins
fig, ax = plt.subplots()
ax.grid(True, alpha=0.3)
plt.plot(x, y)
mpld3.display()
where x & y are arrays of corresponding axis values.
I'm trying to have a jupyter notebook shows a progression of plots in a for loop. The code works, but for some reason the size of the figure changes after the for loop is done. Here's a set of minimal code to illustrate this (in jupyter notebook)
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib notebook
for i in range(10):
plt.gca().scatter(np.random.rand(10),
np.random.rand(10))
plt.gcf().canvas.draw()
plt.gcf().canvas.flush_events()
plt.pause(0.5)
A gif illustrating the issue is attached. This problem has been driving me crazy and changing margins or using tight_layouts() do not help. It seems to be related to how FigureFrame object is rendered. Thanks for the help!
Here comes the advantage of matplotlib.animation into play. It'll make sure the figure is completely drawn before starting the animation.
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def animate(i):
plt.gca().scatter(np.random.rand(10),
np.random.rand(10))
ani = FuncAnimation(plt.gcf(), animate, frames=10, interval=500)
plt.show()
I just upgraded to IPython Notebook version 3.0 and it's disabling the formatting for seaborn. Here's some sample code that replicates the problem
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
data = np.random.randn(100)
fig,ax = plt.subplots(figsize = (11,8.5))
ax.plot(data)
This code works just fine in IPython Notebook V2.4.1 (see http://nbviewer.ipython.org/gist/anonymous/71733c24a68ee464ca40), but in IPython Notebook v3.0, the axes become invisible (see http://nbviewer.ipython.org/gist/anonymous/7525146b07709206908c).
Strangely, in V3, when I switch the order of the seaborn import and the matplotlib inline magic, the plot renders normally the first time I run, then if I re-run, the axes and gridlines disappear. So it seems to have something to do with the inline magic disabling seaborn properties.
Any workarounds, other than not re-executing my imports after the first time?
In iPython Notebook 3.0, add:
seaborn.set_style('darkgrid')
to restore Seaborn default color schemes.