Matplotlib: Displaying and closing a plot using a loop - python-2.7

Using Matplotlib and a for loop, is it possible to display a plot for a given period of time and then have it close when the for loop is done?
I have tried the following, but the plot simply remains open and the loop doesn't end:
import matplotlib.pyplot as plt
import psychopy
x = [34.00,108.00,64.00,99.00,99.00,51.00]
y = [5.00,17.00,11.00,8.00,14.00,5.00]
scatter(x, y, color = "black")
clock = core.Clock()
while clock.getTime() < 10.0:
plt.show()
plt.close()
Thanks

You can use interactive mode plt.ion() in combination with plt.pause().
E.g. to show your window for 5 seconds:
import matplotlib.pyplot as plt
x = [34.00,108.00,64.00,99.00,99.00,51.00]
y = [5.00,17.00,11.00,8.00,14.00,5.00]
plt.scatter(x, y, color = "black")
plt.ion()
plt.draw()
plt.pause(5)

Related

Animating Steronets

I have been looking around and have got to nowhere with this. I am trying to animate the poles on a stereonet diagram. However, the poles do not appear at the location that they should be in.
Figure 1 is the animated pole plot while Figure 2 is how the plot should be. I was wondering if anyone had an idea on how to proceed with this?
import matplotlib as mpl
mpl.use("TkAgg")
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
import mplstereonet
fig, ax = mplstereonet.subplots()
fig2, ax1 = mplstereonet.subplots()
ax.grid(True)
ax1.grid(True)
# Assume a strike and dip with a random variance.
# Current values should plot the poles at either 0, 180
strike, dip = 90, 80
num = 10
strikes = strike + 10 * np.random.randn(num)
dips = dip + 10 * np.random.randn(num)
poles, = ax.pole([], [], 'o')
def init():
poles.set_data([], [])
return poles,
def animate(i):
poles.set_data(strikes[:i], dips[:i])
return poles,
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames = len(strikes), interval = 100, blit=True, repeat=False)
poles1 = ax1.pole(strikes, dips, 'o') # This is how the final image should look like
plt.show()

add multiple colorbars to a subplot of polar contourf [duplicate]

I would like to add a separate colorbar to each subplot in a 2x2 plot.
fig , ( (ax1,ax2) , (ax3,ax4)) = plt.subplots(2, 2,sharex = True,sharey=True)
z1_plot = ax1.scatter(x,y,c = z1,vmin=0.0,vmax=0.4)
plt.colorbar(z1_plot,cax=ax1)
z2_plot = ax2.scatter(x,y,c = z2,vmin=0.0,vmax=40)
plt.colorbar(z1_plot,cax=ax2)
z3_plot = ax3.scatter(x,y,c = z3,vmin=0.0,vmax=894)
plt.colorbar(z1_plot,cax=ax3)
z4_plot = ax4.scatter(x,y,c = z4,vmin=0.0,vmax=234324)
plt.colorbar(z1_plot,cax=ax4)
plt.show()
I thought that this is how you do it, but the resulting plot is really messed up; it just has an all grey background and ignores the set_xlim , set_ylim commands I have (not shown here for simplicity). + it shows no color bars. Is this the right way to do it?
I also tried getting rid of the "cax = ...", but then the colorbar all goes on the bottom right plot and not to each separate plot!
This can be easily solved with the the utility make_axes_locatable. I provide a minimal example that shows how this works and should be readily adaptable:
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
m1 = np.random.rand(3, 3)
m2 = np.arange(0, 3*3, 1).reshape((3, 3))
fig = plt.figure(figsize=(16, 12))
ax1 = fig.add_subplot(121)
im1 = ax1.imshow(m1, interpolation='None')
divider = make_axes_locatable(ax1)
cax = divider.append_axes('right', size='5%', pad=0.05)
fig.colorbar(im1, cax=cax, orientation='vertical')
ax2 = fig.add_subplot(122)
im2 = ax2.imshow(m2, interpolation='None')
divider = make_axes_locatable(ax2)
cax = divider.append_axes('right', size='5%', pad=0.05)
fig.colorbar(im2, cax=cax, orientation='vertical');
In plt.colorbar(z1_plot,cax=ax1), use ax= instead of cax=, i.e. plt.colorbar(z1_plot,ax=ax1)
Specify the ax argument to matplotlib.pyplot.colorbar(), e.g.
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 2)
for i in range(2):
for j in range(2):
data = np.array([[i, j], [i+0.5, j+0.5]])
im = ax[i, j].imshow(data)
plt.colorbar(im, ax=ax[i, j])
plt.show()
Please have a look at this matplotlib example page. There it is shown how to get the following plot with four individual colorbars for each subplot:
I hope this helps.
You can further have a look here, where you can find a lot of what you can do with matplotlib.
Try to use the func below to add colorbar:
def add_colorbar(mappable):
from mpl_toolkits.axes_grid1 import make_axes_locatable
import matplotlib.pyplot as plt
last_axes = plt.gca()
ax = mappable.axes
fig = ax.figure
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cbar = fig.colorbar(mappable, cax=cax)
plt.sca(last_axes)
return cbar
Then you codes need to be modified as:
fig , ( (ax1,ax2) , (ax3,ax4)) = plt.subplots(2, 2,sharex = True,sharey=True)
z1_plot = ax1.scatter(x,y,c = z1,vmin=0.0,vmax=0.4)
add_colorbar(z1_plot)

How to animate and update the title,xlabel,ylabel?

I am new to Matplotlib. Based on my code in following, I wanted to update the data,title,xlabel,ylabel at same time. However, the title and labels did not been updated, but data did.Someone can give me a solution? That will help me a lot.Thank you.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def updata(frame_number):
current_index = frame_number % 3
a = [[1,2,3],[4,5,6],[7,8,9]]
idata['position'][:,0] = np.asarray(a[current_index])
idata['position'][:,1] = np.asarray(a[current_index])
scat.set_offsets(idata['position'])
ax.set_xlabel('The Intensity of Image1')
ax.set_ylabel('The Intensity of Image2')
ax.set_title("For Dataset %d" % current_index)
fig = plt.figure(figsize=(5,5))
ax = fig.add_axes([0,0,1,1])
idata = np.zeros(3,dtype=[('position',float,2)])
ax.set_title(label='lets begin',fontdict = {'fontsize':12},loc='center')
scat = ax.scatter(idata['position'][:,0],idata['position'][:,1],s=10,alpha=0.3,edgecolors='none')
animation = FuncAnimation(fig,updata,interval=2000)
plt.show()
Running the code, I see an empty window. The reason is that the axes span the complete figure (fig.add_axes([0,0,1,1])). In order to see the title and labels, you would need to make the axes smaller than the figure, e.g. by
ax = fig.add_subplot(111)
Also, the scale of the axes is not defined, so the animation will happen outside the axes limits. You can use ax.set_xlim and ax.set_ylim to prevent that.
Here is a complete running code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def updata(frame_number):
current_index = frame_number % 3
a = [[1,2,3],[4,5,6],[7,8,9]]
idata['position'][:,0] = np.asarray(a[current_index])
idata['position'][:,1] = np.asarray(a[current_index])
scat.set_offsets(idata['position'])
ax.set_xlabel('The Intensity of Image1')
ax.set_ylabel('The Intensity of Image2')
ax.set_title("For Dataset %d" % current_index)
fig = plt.figure(figsize=(5,5))
ax = fig.add_subplot(111)
idata = np.zeros(3,dtype=[('position',float,2)])
ax.set_title(label='lets begin',fontdict = {'fontsize':12},loc='center')
scat = ax.scatter(idata['position'][:,0],idata['position'][:,1],
s=25,alpha=0.9,edgecolors='none')
ax.set_xlim(0,10)
ax.set_ylim(0,10)
animation = FuncAnimation(fig,updata,frames=50,interval=600)
plt.show()

Matplotlib - get value of autoscale

Is there a possibility to read the scale of the axis which are set by autoscale?
For example:
import matplotlib.pyplot as plt
x=[1,2,3,4,5]
y=[1,2,3,4,5]
plt.plot(x,y)
plt.grid(True)
fig = plt.gcf()
plt.show()
I want to get the scale of the x and the y axis. In this case it would be 0.5.
After the plotting, you can do
# calculate x scale
ax = fig.gca()
foo = ax.get_xmajorticklabels()
bar = [float(foo[i].get_text()) for i in range(len(foo))]
scale_x = bar[1]-bar[0]
# calculate y scale
foo = ax.get_ymajorticklabels()
bar = [float(foo[i].get_text()) for i in range(len(foo))]
scale_y = bar[1]-bar[0]
print scale_x, scale_y
This only works after plt.show() is called (unclear to me, maybe a separate question for SO), but it works. Just append those lines to your script.

Python how to plot graph sine wave

I have this signal :
from math import*
Fs=8000
f=500
sample=16
a=[0]*sample
for n in range(sample):
a[n]=sin(2*pi*f*n/Fs)
How can I plot a graph (this sine wave)?
and create name of xlabel as 'voltage(V)' and ylabel as 'sample(n)'
What code to do this?
I am so thanksful for help ^_^
Setting the x-axis with np.arange(0, 1, 0.001) gives an array from 0 to 1 in 0.001 increments.
x = np.arange(0, 1, 0.001) returns an array of 1000 points from 0 to 1, and y = np.sin(2*np.pi*x) you will get the sin wave from 0 to 1 sampled 1000 times
I hope this will help:
import matplotlib.pyplot as plt
import numpy as np
Fs = 8000
f = 5
sample = 8000
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
plt.plot(x, y)
plt.xlabel('sample(n)')
plt.ylabel('voltage(V)')
plt.show()
P.S.: For comfortable work you can use The Jupyter Notebook.
import matplotlib.pyplot as plt # For ploting
import numpy as np # to work with numerical data efficiently
fs = 100 # sample rate
f = 2 # the frequency of the signal
x = np.arange(fs) # the points on the x axis for plotting
# compute the value (amplitude) of the sin wave at the for each sample
y = np.sin(2*np.pi*f * (x/fs))
#this instruction can only be used with IPython Notbook.
% matplotlib inline
# showing the exact location of the smaples
plt.stem(x,y, 'r', )
plt.plot(x,y)
import numpy as np
import matplotlib.pyplot as plt
F = 5.e2 # No. of cycles per second, F = 500 Hz
T = 2.e-3 # Time period, T = 2 ms
Fs = 50.e3 # No. of samples per second, Fs = 50 kHz
Ts = 1./Fs # Sampling interval, Ts = 20 us
N = int(T/Ts) # No. of samples for 2 ms, N = 100
t = np.linspace(0, T, N)
signal = np.sin(2*np.pi*F*t)
plt.plot(t, signal)
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
import math
import turtle
ws = turtle.Screen()
ws.bgcolor("lightblue")
fred = turtle.Turtle()
for angle in range(360):
y = math.sin(math.radians(angle))
fred.goto(angle, y * 80)
ws.exitonclick()
The window of usefulness has likely come and gone, but I was working at a similar problem. Here is my attempt at plotting sine using the turtle module.
from turtle import *
from math import *
#init turtle
T=Turtle()
#sample size
T.screen.setworldcoordinates(-1,-1,1,1)
#speed up the turtle
T.speed(-1)
#range of hundredths from -1 to 1
xcoords=map(lambda x: x/100.0,xrange(-100,101))
#setup the origin
T.pu();T.goto(-1,0);T.pd()
#move turtle
for x in xcoords:
T.goto(x,sin(xcoords.index(x)))
A simple way to plot sine wave in python using matplotlib.
import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0,3*np.pi,0.1)
y=np.sin(x)
plt.plot(x,y)
plt.title("SINE WAVE")
plt.show()
import matplotlib.pyplot as plt
import numpy as np
#%matplotlib inline
x=list(range(10))
def fun(k):
return np.sin(k)
y=list(map(fun,x))
plt.plot(x,y,'-.')
#print(x)
#print(y)
plt.show()
This is another option
#!/usr/bin/env python
import numpy as np
import matplotlib
matplotlib.use('TKAgg') #use matplotlib backend TkAgg (optional)
import matplotlib.pyplot as plt
sample_rate = 200 # sampling frequency in Hz (atleast 2 times f)
t = np.linspace(0,5,sample_rate) #time axis
f = 100 #Signal frequency in Hz
sig = np.sin(2*np.pi*f*(t/sample_rate))
plt.plot(t,sig)
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.tight_layout()
plt.show()
Yet another way to plot the sine wave.
import numpy as np
import matplotlib
matplotlib.use('TKAgg') #use matplotlib backend TKAgg (optional)
import matplotlib.pyplot as plt
t = np.linspace(0.0, 5.0, 50000) # time axis
sig = np.sin(t)
plt.plot(t,sig)
from math import *
Fs = 8000
f = 500
sample = 16
a = [0] * sample
for n in range(sample):
a[n] = sin(2*pi*f*n/Fs)
creating the x coordinates
Sample = [i for i in range(sample)]
importing matplotlib for plotting
import matplotlib.pyplot as plt
adding labels and plotting
plt.xlabel('Voltage(V)')
plt.ylabel('Sample(n)')
plt.plot(Sample, a)
plt.show()