How to get any kind of interactive plot with ipywidgets and matplotlib - matplotlib

I am just looking for some kind of working example which will allow me to have a slider and a sine wave plot whereby I can vary the frequency in a Jupyter Notebook. All the online demos that I have Googled don't work for me. The issue seems to be that the old matplotlib graph is not erased before the new one is created.
Here is my minimal example
import ipywidgets as widgets
from IPython.display import display, clear_output
import matplotlib.pyplot as plt
import numpy as np
def f(a):
clear_output(wait=True)
fig, ax = plt.subplots()
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(a*x)
ax.grid()
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.plot(x,y)
ax.set_title("y = sin(x)")
%matplotlib inline
from time import sleep
for i in range(1,10):
clear_output(wait=True)
f(i)
sleep(1)
I have also tried
out = widgets.Output(layout={'border': '1px solid black'})
with out:
widgets.interact(f, a=1)
out.clear_output()
display(out)
However nothing I try will erase the previous matplotlib graph. They just all pile up on top of each other. I admit I am floundering as I don't really understand the API that well and the example in the documentation don't work for me.
I don't expect people to fix my code as it is probably rubbish. I am just looking for a working example which will allow me to interactively control the frequency and redraw the sine wave on a Jupyter notebook.

Here is a minimal example that works for me:
from ipywidgets import interact
import ipywidgets as widgets
import matplotlib.pyplot as plt
import numpy as np
def plot(freq):
x = np.linspace(0, 2*np.pi)
y = np.sin(x * freq)
plt.plot(x, y)
interact(plot, freq = widgets.FloatSlider(value=2, min=0.1, max=5, step=0.1))
default plot:
Screenshot of notebook after moving the slider to the right:

Related

Scale Y axis of matplotlib plot in jupyter notebook

I want to scale Y axis so that I can see values, as code below plots cant see anything other than a thin black line. Changing plot height doesn't expand the plot.
import numpy as np
import matplotlib.pyplot as plt
data=np.random.random((4,10000))
plt.rcParams["figure.figsize"] = (20,100)
#or swap line above with one below, still no change in plot height
#fig=plt.figure(figsize=(20, 100))
plt.matshow(data)
plt.show()
One way to do this is just repeat the values then plot result, but I would have thought it possible to just scale the height of the plot?
data_repeated = np.repeat(data, repeats=1000, axis=0)
You can do it like this:
import numpy as np
import matplotlib.pyplot as plt
data=np.random.random((4, 10000))
plt.figure(figsize=(40, 10))
plt.matshow(data, fignum=1, aspect='auto')
plt.show()
Output:

how to remove all indicators from pyplot.polar

i need to make a polar plot with just the main data content visible.
for now i have managed to get the following image by using these simple codes.
but there is still one outline circle left around it. how can i remove it
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
data = np.random.randint(1800,2200,(24*60))
data = list(data)
data.append(data[0])
print(data)
theta = np.arange(0,360+360/(24*60),360/(24*60))*np.pi/180
plt.polar(theta, data)
plt.xticks([])
plt.yticks([])
plt.savefig("p.png")
plt.show()
This should do the trick:
plt.box(on=None)
Solution inspired from the Q: Removing frame while keeping axes in pyplot subplots

plot shuffled array numpy

I am writting a very simple script, one that plot a sin using jupyter notebook (python 3). when I put:
import numpy
import matplotlib.pyplot as plt
x=np.arange(0.0,5*np.pi,0.001)
y = np.sin(x)
plt.plot(x,y)
The plot is fine.
However if :
import numpy
import matplotlib.pyplot as plt
x=np.arange(0.0,5*np.pi,0.001)
np.random.shuffle(x)
y = np.sin(x)
plt.plot(x,y)
the image is
I don't understand why shuffling the x BEFORE I ran sin does it.
thank you
Let's first simplify things a bit. We plot 4 points and annote them with the order in which they are plotted.
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
x=np.arange(4)
y = np.sin(x)
plt.plot(x,y, marker="o")
for i, (xi,yi) in enumerate(zip(x,y)):
plt.annotate(str(i), xy=(xi,yi), xytext=(0,4),
textcoords="offset points", ha="center")
plt.show()
No if we shuffle x and plot the same graph,
x=np.arange(4)
np.random.shuffle(x)
y = np.sin(x)
we see that positions of the points are still are the same, but while e.g. previously the first point was the one at (0,0), it's now the third one appearing there. Due to this randomized order, the connecting lines go zickzack.
Now if you use enough points, all those lines will add up to look like a complete surface, which is what you get in your image.

Usetex in Matplotlib

When I try to obtain plots in which the axis (both formulae and text) are written in LaTeX standard roman font, I keep not obtaining the plot, but the code runs without warnings. In particular, this simple scatter with TeX code in the axis labels, in which I have put my better understanding of the documentation:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
x = np.linspace(0,1,100)
y = np.random.rand(100,1)
plt.rc('text', usetex=True)
plt.rc('font', family='roman')
plt.scatter(x, y, c='b', s=10)
plt.xlabel(r'$\lambda$ ($\AA$)',size='12')
plt.ylabel(r'$F_\alpha (W/m^2)$ ',size='12')
plt.title(r'A title in \LaTeX typography')
plt.show()
keeps yielding a message like <matplotlib.figure.Figure at 0x1f75d4750>, which I have met before, but I keep failing when trying to remedy this one. In addition, saving the plot (png or pdf) would not solve the issue, and if the problem is related to TeX, I have definitely not found any resource that can help. I use MacOS Sierra.

Basic axis malfuction in matplotlib

When plotting using matplotlib, I ran into an interesting issue where the y axis is scaled by a very inconvenient quantity. Here's a MWE that demonstrates the problem:
import numpy as np
import matplotlib.pyplot as plt
l = np.linspace(0.5,2,2**10)
a = (0.696*l**2)/(l**2 - 9896.2e-9**2)
plt.plot(l,a)
plt.show()
When I run this, I get a figure that looks like this picture
The y-axis clearly is scaled by a silly quantity even though the y data are all between 1 and 2.
This is similar to the question:
Axis numerical offset in matplotlib
I'm not satisfied with the answer to this question in that it makes no sense to my why I need to go the the convoluted process of changing axis settings when the data are between 1 and 2 (EDIT: between 0 and 1). Why does this happen? Why does matplotlib use such a bizarre scaling?
The data in the plot are all between 0.696000000017 and 0.696000000273. For such cases it makes sense to use some kind of offset.
If you don't want that, you can use you own formatter:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
l = np.linspace(0.5,2,2**10)
a = (0.696*l**2)/(l**2 - 9896.2e-9**2)
plt.plot(l,a)
fmt = matplotlib.ticker.StrMethodFormatter("{x:.12f}")
plt.gca().yaxis.set_major_formatter(fmt)
plt.show()