Pass variable to Ipython Widget - python

I have a simple widget that modifies a plot, here is the definition:
#Plot function
def plf(x,lm,ls):
plt.plot(x[lm:ls],np.sin(x)[lm:ls])
this function takes a list x an plot sin(x), lm and ls controls the number of data that is ploted, the problem is when i try to plot a determinated list of data, for example
list = [1,2,3,4,5,6,7,8,9]
and if i try
interact(plf,x=list,lm=(0,max(x)//2,1),ls=(max(x)//2,max(x),1))
throws me the error:
NameError: name 'x' is not defined
so, how can i define x so it can be any list that i want?

Is this what you are trying to do?
%matplotlib inline
from IPython.html.widgets import interact, fixed
import matplotlib.pyplot as plt
import numpy as np
def plf(x,lm,ls):
plt.plot(x[lm:ls],np.sin(x)[lm:ls])
data = [1,2,3,4,5,6,7,8,9]
max_lm = max(data)//2
max_ls = max(data)
interact(plf,x=fixed(data),lm=(0,max_lm,1),ls=(max_lm, max_ls,1))

Related

Python Widget - How made this plot?

I know that if I want plot/print something with the widget, i should use the following code:
interact(function,variable=(1,3))
Now I am facing a problem. Is it possible create a widget that have as input two arrays? for example, consider the case when:
a= np.linspace(1,2,100)
b= np.linspace(3,4,100)
Is it possible see the behaviour of a function, with two different arrays (e.g. switch from the interval a, to the interval b)?
Below I have tried something, but it does not works..
import numpy as np
import matplotlib.pyplot as plt
from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
a= np.linspace(1,2,100)
b= np.linspace(3,4,100)
def test(array,constant):
f = []
for x in array:
f.append(x**2+constant*x)
plt.plot(f)
plt.show()
return f
interact(test,array=(a,b),constant=(1,5))
You can try something like this:
import numpy as np
import matplotlib.pyplot as plt
from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
xs = {"a": np.linspace(1, 2, 100), "b": np.linspace(3, 4, 100)}
def test(constant, array):
x = xs[array]
f = x**2*constant*x
plt.plot(x, f)
plt.show()
interact(test, array=xs.keys(), constant=(1,5))
It will create a widget with a slider to control the constant value and a pull down menu to select one of the two arrays.

How to save multiple figure objects without knowing their variable names beforehand [duplicate]

I would like to:
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
# ...
for i, figure in enumerate(pylab.MagicFunctionReturnsListOfAllFigures()):
figure.savefig('figure%d.png' % i)
What is the magic function that returns a list of current figures in pylab?
Websearch didn't help...
Pyplot has get_fignums method that returns a list of figure numbers. This should do what you want:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(100)
y = -x
plt.figure()
plt.plot(x)
plt.figure()
plt.plot(y)
for i in plt.get_fignums():
plt.figure(i)
plt.savefig('figure%d.png' % i)
The following one-liner retrieves the list of existing figures:
import matplotlib.pyplot as plt
figs = list(map(plt.figure, plt.get_fignums()))
Edit: As Matti Pastell's solution shows, there is a much better way: use plt.get_fignums().
import numpy as np
import pylab
import matplotlib._pylab_helpers
x=np.random.random((10,10))
y=np.random.random((10,10))
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
figures=[manager.canvas.figure
for manager in matplotlib._pylab_helpers.Gcf.get_all_fig_managers()]
print(figures)
# [<matplotlib.figure.Figure object at 0xb788ac6c>, <matplotlib.figure.Figure object at 0xa143d0c>]
for i, figure in enumerate(figures):
figure.savefig('figure%d.png' % i)
This should help you (from the pylab.figure doc):
call signature::
figure(num=None, figsize=(8, 6),
dpi=80, facecolor='w', edgecolor='k')
Create a new figure and return a
:class:matplotlib.figure.Figure
instance. If num = None, the
figure number will be incremented and
a new figure will be created.** The
returned figure objects have a
number attribute holding this number.
If you want to recall your figures in a loop then a good aproach would be to store your figure instances in a list and to call them in the loop.
>> f = pylab.figure()
>> mylist.append(f)
etc...
>> for fig in mylist:
>> fig.savefig()
Assuming you haven't manually specified num in any of your figure constructors (so all of your figure numbers are consecutive) and all of the figures that you would like to save actually have things plotted on them...
import matplotlib.pyplot as plt
plot_some_stuff()
# find all figures
figures = []
for i in range(maximum_number_of_possible_figures):
fig = plt.figure(i)
if fig.axes:
figures.append(fig)
else:
break
Has the side effect of creating a new blank figure, but better if you don't want to rely on an unsupported interface
I tend to name my figures using strings rather than using the default (and non-descriptive) integer. Here is a way to retrieve that name and save your figures with a descriptive filename:
import matplotlib.pyplot as plt
figures = []
figures.append(plt.figure(num='map'))
# Make a bunch of figures ...
assert figures[0].get_label() == 'map'
for figure in figures:
figure.savefig('{0}.png'.format(figure.get_label()))

Using hashlib on a matplotlib object

Using Python, I am trying to write tests that compare the current output with an expected output. The output is a matplotlib figure and I would like to do this without saving the figure to a file.
I had the idea to find the cryptographic hash of the object so that I would just need to compare one hash with another to confirm that the entire object is unchanged from what is expected.
This works fine for a numpy array as follows:
import numpy as np
import hashlib
np.random.seed(1)
A = np.random.rand(10,100)
actual_hash = hashlib.sha1(A).hexdigest()
expected_hash = '38f682cab1f0bfefb84cdd6b112b7d10cde6147f'
assert actual_hash == expected_hash
When I try this on a matplotlib object I get: TypeError: object supporting the buffer API required
import hashlib
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(0,100,1000)
Y = np.sin(0.5*X)
plt.plot(X,Y)
fig = plt.gcf()
actual_hash = hashlib.sha1(fig).hexdigest() #this raises the TypeError
Any ideas how I can use hashlib to find the cryptographic hash of a matplotlib object?
Thanks.
You can get the figure as a numpy array using buffer_rgba(). Before using it you must actually draw the figure:
draw must be called at least once before this function will work and
to update the renderer for any subsequent changes to the Figure.
import hashlib
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(0,100,1000)
Y = np.sin(0.5*X)
plt.plot(X,Y)
canvas = plt.gcf().canvas
canvas.draw()
actual_hash = hashlib.sha1(np.array(canvas.buffer_rgba())).hexdigest()

How to scatter plot a two dimensional list in python?

How can I scatter plot a list of pairs with each axis of the plot representing one of the value in the pair in python? My list looks like this
[(62725984, 63548262), (64797631, 64619047), (65069350, 65398449), (58960696, 57416785), (58760119, 58666604), (60470606, 61338129), (60728760, 59001882)]
This should be easy. You can extract the pair into two variables as follows:
x,y = zip(*<name_of_your_2d_list>)
Also, you can pass the same to scatter function as
matplotlib.pyplot.scatter(*zip(*<name_of_your_2d_list>).
Try the following. It should work:
import matplotlib.pyplot, pylab
data = [(62725984, 63548262), (64797631, 64619047), (65069350, 65398449), (58960696, 57416785), (58760119, 58666604), (60470606, 61338129), (60728760, 59001882)]
matplotlib.pyplot.scatter(*zip(*data))
matplotlib.pyplot.show()
try below code:
import matplotlib.pyplot
import pylab
list1 = [(62725984, 63548262), (64797631, 64619047), (65069350, 65398449), (58960696, 57416785), (58760119, 58666604), (60470606, 61338129), (60728760, 59001882)]
list1 = list(zip(*list1))
pylab.scatter(list(list1[0]),list(list1[1]))
pylab.show()
You can use the function below.
import matplotlib.pyplot as plt
def scatter_plot(list):
x = []
y = []
for i in list:
x.append(i[0])
y.append(i[1])
plt.scatter(x,y)
plt.show()
And simply use this function as below.
scatter_plot(list_of_list)

matplotlib: Continuously overwriting

I would like to plot my intermediate results and want to see how is the algorithm progressing. I have posted a demo code too. Lets say my algorithm goes for 20 epochs and I want to plot the result of every epoch in a same file. I tried with following demo code. But I can not see any plot on a.png.
Could someone help me how could I do it?
import matplotlib.pylab as plt
import numpy as np
for i in range(20):
y = np.random.random()
plt.plot(i, y)
plt.savefig('a.png')
You have to provide the whole history in your variables e.g. as a list:
import matplotlib.pylab as plt
import numpy as np
# creates two lists with the same length
x = range(20)
y = [0] * 20
for i in x:
y.insert(i, np.random.random())
plt.plot(x, y)
plt.savefig('plot_%d.png' % i)

Categories