I am producing a few hundred matplotlib plots, I work in Jupyter Notebook. Each have it's own title. I want to be able to search for these titles. So when I download the file as html, and open it in browser, I'd like to find the title via using ctrl-f. How can I do that?
More details, here is an MCVE:
import matplotlib.pyplot as plt
x=range(5);y=range(5)
for i in range(6):
plt.figure()
plt.plot(x,y)
plt.title("Title"+str(i))
This produces nice plots, titled Title0 Title1 ... Title5. Howevere, these titles are part of the file and not searchable by ctrl-f, or browser doesn't detect them as text, though it would be desired.
I can do it in gnuplot but now I'd like to stick to Python.
You can generate markdown within a Jupyter notebook. Try this:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from IPython.display import display, Markdown
display(Markdown('Title of graph goes here'))
x = np.linspace(0, 10, 30)
y = np.sin(x)
plt.plot(x, y, 'o', color='black');
Edit: I've just realised that in your example all the titles will be printed before the graphs. The solution is:
import matplotlib.pyplot as plt
# DO NOT USE %matplotlib inline
x=range(5);y=range(5)
for i in range(6):
ax = plt.figure()
_ = plt.plot(x,y)
title = "Title"+str(i)
display(Markdown(title))
display(ax)
You may print title for every figure (plt.show() necessary in this case):
import matplotlib.pyplot as plt
x=range(5);y=range(5)
for i in range(2):
plt.figure()
plt.plot(x,y)
plt.title("Title"+str(i))
print("Title"+str(i))
plt.show()
Related
How can I make a ipywidget button in a Jupyter notebook update a plot in a specific axis?
I already know how to make a button update a plot when using a single axis, like so:
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
btn = widgets.Button(description='Click')
display(btn)
output = widgets.Output()
def on_click_fn(obj):
output.clear_output()
values = np.random.rand(10)
with output:
plt.plot(values)
plt.show()
btn.on_click(on_click_fn)
display(output)
In this example, clicking the button updates the plot and shows a new set of 10 random points. I thought it would be simple to extend this to updating a specific axis, and attempted the following:
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
btn = widgets.Button(description='Click')
display(btn)
output = widgets.Output()
fig, ax = plt.subplots(ncols=2)
def on_click_fn(obj):
output.clear_output()
values = np.random.rand(10)
with output:
ax[0].plot(values)
plt.show()
btn.on_click(on_click_fn)
display(output)
However, clicking the button in this example does not seem to do anything. I tried different combinations of adding/removing the plt.show() call, using fig.draw() instead, using fig.canvas.draw_idle(), etc, without much success. What's the correct, least "hacky" way of accomplishing this?
Note: This question is only about how to make a button update a plot, like my first example, instead of making the button update a specific axis only.
with this code
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
%matplotlib widget
btn = widgets.Button(description='Click')
display(btn)
output = widgets.Output()
fig, ax = plt.subplots(ncols=2)
def on_click_fn(obj):
output.clear_output()
values = np.random.rand(10)
with output:
ax[0].plot(values)
plt.show()
btn.on_click(on_click_fn)
display(output)
I got this output
import numpy as np
from matplotlib_venn import venn2, venn2_circles, venn2_unweighted
from matplotlib_venn import venn3, venn3_circles
from matplotlib import pyplot as plt
plt.title(print("Shared",Signature_1, 'and',Signature_2, 'and',Signature_3))
venn3(subsets = (len(NameA), len(NameB), len(shared_A_B), len(NameC), len(shared_A_C),
len(shared_C_B), len(shared_A_B_C)), set_labels = (Signature_1, Signature_2, Signature_3), alpha = 0.5)
plt.show()
This code produces titles for plots in jupyter notebook only. When I run the .py script in Anaconda prompt only the plot is visible. How would I go about getting the titles to appear in the plot window? I realized because these are formatted to take variables [plt.title(print("title",variable,etc.)] that they do not work in command line. Any suggestions would be appreciated
You can use the .format method to include a variable into the print/title.
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0,10)
y = x**2
plt.plot(x,y)
variable ='IamVar'
Signature_1='one'
Signature_2='two'
Signature_3='three'
# \n stands for newline
plt.suptitle("Moving title - {} and {},{} \n set=({},{})".format(Signature_1,Signature_2,Signature_3,len(x),len(y))
,size=8,x=0.3, y=0.6)
plt.show()
I have a problem using Seaborn relplot when trying to make an animation. I have recreated the issue I have using one of the datasets that comes with Seaborn, below.
I suspect it is something to do with the plt.figure() not being the same as the sns.relplot. Any ideas on how to make this work would be greatly received. Thanks.
%matplotlib inline
import seaborn as sns
import pandas as pd
from matplotlib import pyplot as plt
from celluloid import Camera
from IPython.display import HTML
import ffmpeg
df = sns.load_dataset('car_crashes')
f = plt.figure(figsize=(3,3))
camera = Camera(f)
# This might seem a little bit unnecessary, but its emulating the way I am plotting my other data source:
for i in range(0, len(df), 10):
g = sns.relplot(x='total', y='abbrev', hue='abbrev', data=df.iloc[i:i+10 , [0,7]])
plt.axis('off')
plt.title(f'THIS IS THE TITLE OF {i}')
plt.gca().set_aspect('equal')
camera.snap()
animation = camera.animate()
HTML(animation.to_html5_video())
So, for the following code no graph is printed in jupyter notebook. If I use plt.scatter then it does produce graph. Any suggestions what could be wrong? Can it be caused by the data?
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def calc_gauss(df, index):
x=df.iloc[[index]]
mean = df.apply(lambda x: x.mean(), axis=1)
mu=mean.iloc[[index]]
std = df.std(axis=1)
sig=std.iloc[[index]]
dens = norm.pdf(x,mu,sig)
# build the plot
fig, ax = plt.subplots(figsize=(9,6))
plt.style.use('fivethirtyeight')
ax.plot(x, dens)
return plt.show()
calc_gauss(df_distance, 339)
Instead of
return plt.show()
use
fig.show()
If you want the picture to show in the notebook, use %matplotlib inline in a cell evaluated before the show command
Note the problem was that the arrays were shape (1,24). plot likes only 1D arrays. Replacing ax.plot(x, dens) with ax.plot(x.reshape(-1), dens.reshape(-1)) solved the issue.
I have a function that creates a figure and for some reason it is shown in Jupyter notebook twice, even though I didn't run show at all. I pass the fig and ax as an output of this function, and plan to show it only later.
I get confused between plt, fig and ax functionaries and guess that the answer is hidden somewhere there.
Here is an anonymised version of my code:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
def plot_curve(dummydata):
# builds a chart
fig,ax = plt.subplots(1) # get subplots
fig.set_figheight(7)
fig.set_figwidth(12) #set shape
plt.plot(dummydata.x1, dummydata.y1,label = 'l1') #curve 1
plt.plot(dummydata.x2, dummydata.y2,label = 'l2') #curve2
plt.xlabel('xlabel') #labels
plt.ylabel('xlabel')
plt.yscale('linear') #scale and bounds
plt.ylim(0,100)
ymin,ymax= ax.get_ylim()
ax.axhline(1, color='k', linestyle=':', label = 'lab1') #guideline - horizontal
ax.axvline(2, color='r',linestyle='--', label = 'lab2') #guideline - vertical
ax.axvline(3, color='g',linestyle='--', label = 'lab3') #guideline - vertical
ax.arrow(1,2,3,0, head_width=0.1, head_length=0.01, fc='k', ec='k') # arrow
rect = mpl.patches.Rectangle((1,2), 2,3, alpha = 0.1, facecolor='yellow',
linewidth=0 , label= 'lab4') #yellow area patch
ax.add_patch(rect)
plt.legend()
plt.title('title')
return fig,ax
and then call it with:
for i in range(3):
dummydata = pd.DataFrame({
'x1':np.arange(1+i,100,0.1),
'y1':np.arange(11+i,110,0.1),
'x2':np.arange(1+i,100,0.1),
'y2':np.arange(21+i,120,0.1)
})
fig,ax = plot_curve(dummydata) #get the chart
What should I change to not show the figure by default, and show it only by my command?
Thanks
Try disabling matplotlib interactive mode using plt.ioff(). With interactive mode disabled the plots will only be shown with an explicit plt.show().
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
# Desactivate interactive mode
plt.ioff()
def plot_curve(dummydata):
# the same code as before
Then in another cell
for i in range(3):
dummydata = pd.DataFrame({
'x1':np.arange(1+i,100,0.1),
'y1':np.arange(11+i,110,0.1),
'x2':np.arange(1+i,100,0.1),
'y2':np.arange(21+i,120,0.1)
})
# I'am assuming this should not be in the for loop
# The plot will NOT be shown because we are not in interactive mode
fig, ax = plot_curve(dummydata) #get the chart
No plot will be shown yet.
Now in another cell
# Now ANY plot (figure) which was created and not shown yet will be finally shown
plt.show()
The plot is finally shown. Note that if you have created several plots all of them will be shown now.
Try this:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib
With this importing you should not see the figure after plotting.
But you can see the figure by writing fig to IPython cell:
dummydata = pd.DataFrame({
'x1':np.arange(1,100,0.1),
'y1':np.arange(11,110,0.1),
'x2':np.arange(1,100,0.1),
'y2':np.arange(21,120,0.1)
})
fig,ax = plot_curve(dummydata) #get the chart
fig # Will now plot the figure.
Is this the desired output?