Why does this plot not update ? (matplotlib) - matplotlib

Code below, I want to write a code that updates its function by cearing the axes and assigning new plots. It works when I only have one plot, but doesnt when I use subplots()...
Thanks
import numpy as np
import matplotlib.pyplot as plt
import time
fig , ax = plt.subplots(1,2)
x = np.linspace(0,10,10)
alpha = 0.70
def sin(x):
return np.sin(alpha*x)
def lin(x):
return alpha*x
for i in range(5):
ax[0].clear()
ax[1].clear()
ax[0].plot(x,lin(x), marker='o', label = str(i))
ax[1].plot(x,sin(x), marker='o')
fig.legend()
plt.show()
alpha = alpha**2
time.sleep(0.5)

Related

Curve fitting exponential function with semilog x-axis

I'm having trouble fitting some date onto an exponential function with a semilog x-axis.
Following is the code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
kd=np.array[0.735420099, 0.700823723, 0.647775947,0.613179572,0.573970346,0.54398682,0.454036244,0.371004942,0.292586491,0.271828666,0.21878089,0.165733114,0.157660626,0.151894563]
ADAR = np.array[0.001012268,0.002028379,0.004015198,0.005931555,0.007948127,0.010143277,0.019594977,0.039746044,0.076782168,0.101639121,0.193968714,0.574178304,0.778822803,0.9878803]
def func(x,a,c,d):
return a*np.exp(-c*x)+d
init_v = (1,1e-6,0)
opt,pcov = curve_fit(func,ADAR,kd,init_v)
a,c,d = opt
x2 = np.linspace(0.001,1)
y2 = func(x2,a,c,d)
plt.grid(True, which = "both")
fig = plt.figure()
ax = plt.gca()
ax.scatter(ADAR,kd, c = 'blue')
ax.set_xscale('log')
plt.xlim([0.001,1])
plt.ylim([0,0.8])
plt.plot(x2,y2, '-', label = 'fit')
plt.legend()
plt.title('Area pressure coefficient')
plt.xlabel('AD/AR')
plt.ylabel('kd')
plt.show
Trying to fit the scatter plot:
Using Scipy Curve_fit with initial guesses I am unable to get a close fit of the data. Am I using the wrong function for this?

I have been trying to embed my matplotlib graph into a pyqt5 application with a moving graph any help is appreciated

This code displays a moving graph with two lines, and the data is saved to a CSV file with the code that makes the data. I have tried to create a canvas class using the pyqt5 imports, but I am struggling with where exactly to put the matplotlib code.
from itertools import count
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.animation import FuncAnimation
plt.style.use('fivethirtyeight')
x_vals = []
y_vals = []
index = count()
def animate(i):
data = pd.read_csv("C:/Users/Khata/PycharmProjects/LiveData1/venv/data.csv")
x = data['x_value']
y1 = data['total_1']
y2 = data['total_2']
plt.cla()
plt.plot(x, y1, label='Channel 1')
plt.plot(x, y2, label='Channel 2')
plt.legend(loc='upper left')
plt.tight_layout()
ani = FuncAnimation(plt.gcf(), animate, interval=1000)
plt.tight_layout()
plt.show()

Matplotlib line chart animation

I am trying to animate a simple line chart with 2 equal arrays. I've seen some guides online but honestly, I'm not sure what I'm doing here, am I close to the solution?
I'm looking for this: https://miro.medium.com/max/1126/1*j0LxVQPbwtQDpL17TH9gZw.gif
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
x = np.array([1,2,3,4,5,6,7,8])
y = np.array([6,9,12,42,50,62,76,82])
fig = plt.figure()
ax = plt.axes(xlim=(1, 8), ylim=(6, 82))
line, = ax.plot([], [], lw=2)
def init():
line.set_data([], [])
return line,
def animate(i):
line.set_ydata(x[i:])
line.set_xdata(y[i:])
return line,
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=20, blit=True)
anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
plt.show()
We are changing the way the data is set up. And I changed the number of frames to 9 because the number of data is 8. In addition, I used PIL to create GIF images, so please correct it.
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from IPython.display import HTML
from matplotlib.animation import PillowWriter
x = np.array([1,2,3,4,5,6,7,8])
y = np.array([6,9,12,42,50,62,76,82])
fig = plt.figure()
ax = plt.axes(xlim=(1, 8), ylim=(6, 82))
line, = ax.plot([], [], lw=2)
def init():
line.set_data([], [])
return line,
def animate(i):
line.set_data(x[:i],y[:i])
return line,
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=9, interval=200, blit=True)
# anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
# plt.show()
anim.save('plot_ani.gif', writer='pillow')

matlibplot graphing inside a button

I'm wondering why my matlibplot is currently graphing inside a button as shown below:
Code is shown below
from gui export Index
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
fig, ax = plt.subplots()
plt.subplots_adjust(buttom-0.2)
pos_trim = plt.axes([0.20, 0.05, .1, 0.075])
b_trim = Button(pos_trim, 'Trim', hoverclor='0.25')
callback = Index(c)
b_trim.on_clicked(callback.autoTrim) # from gui.index
freqs = np.arange(2,20,3)
t = np.arange(0.0, 1.0, 0.05)
s = np.sin(2*np.pi*freqs[0]*t)
l, = plt.plot(t,s,lw=2)
plt.show()
Index class:
class Index:
def __init__(self, chart):
self.__chart = chart
def autoTrim(self, event):
print "Autotrim"
#self.__chart.autoTrim()
plt.draw()
Try changing your line where you plot the data to:
l, = ax.plot(t,s,lw=2)
That is, plot to the axes you created for the plot (ax). Otherwise, you're plotting to the last axes you created, which in this case, is the button.

Embedding small plots inside subplots in matplotlib

If you want to insert a small plot inside a bigger one you can use Axes, like here.
The problem is that I don't know how to do the same inside a subplot.
I have several subplots and I would like to plot a small plot inside each subplot.
The example code would be something like this:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
for i in range(4):
ax = fig.add_subplot(2,2,i)
ax.plot(np.arange(11),np.arange(11),'b')
#b = ax.axes([0.7,0.7,0.2,0.2])
#it gives an error, AxesSubplot is not callable
#b = plt.axes([0.7,0.7,0.2,0.2])
#plt.plot(np.arange(3),np.arange(3)+11,'g')
#it plots the small plot in the selected position of the whole figure, not inside the subplot
Any ideas?
I wrote a function very similar to plt.axes. You could use it for plotting yours sub-subplots. There is an example...
import matplotlib.pyplot as plt
import numpy as np
#def add_subplot_axes(ax,rect,facecolor='w'): # matplotlib 2.0+
def add_subplot_axes(ax,rect,axisbg='w'):
fig = plt.gcf()
box = ax.get_position()
width = box.width
height = box.height
inax_position = ax.transAxes.transform(rect[0:2])
transFigure = fig.transFigure.inverted()
infig_position = transFigure.transform(inax_position)
x = infig_position[0]
y = infig_position[1]
width *= rect[2]
height *= rect[3] # <= Typo was here
#subax = fig.add_axes([x,y,width,height],facecolor=facecolor) # matplotlib 2.0+
subax = fig.add_axes([x,y,width,height],axisbg=axisbg)
x_labelsize = subax.get_xticklabels()[0].get_size()
y_labelsize = subax.get_yticklabels()[0].get_size()
x_labelsize *= rect[2]**0.5
y_labelsize *= rect[3]**0.5
subax.xaxis.set_tick_params(labelsize=x_labelsize)
subax.yaxis.set_tick_params(labelsize=y_labelsize)
return subax
def example1():
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
rect = [0.2,0.2,0.7,0.7]
ax1 = add_subplot_axes(ax,rect)
ax2 = add_subplot_axes(ax1,rect)
ax3 = add_subplot_axes(ax2,rect)
plt.show()
def example2():
fig = plt.figure(figsize=(10,10))
axes = []
subpos = [0.2,0.6,0.3,0.3]
x = np.linspace(-np.pi,np.pi)
for i in range(4):
axes.append(fig.add_subplot(2,2,i))
for axis in axes:
axis.set_xlim(-np.pi,np.pi)
axis.set_ylim(-1,3)
axis.plot(x,np.sin(x))
subax1 = add_subplot_axes(axis,subpos)
subax2 = add_subplot_axes(subax1,subpos)
subax1.plot(x,np.sin(x))
subax2.plot(x,np.sin(x))
if __name__ == '__main__':
example2()
plt.show()
You can now do this with matplotlibs inset_axes method (see docs):
from mpl_toolkits.axes_grid.inset_locator import inset_axes
inset_axes = inset_axes(parent_axes,
width="30%", # width = 30% of parent_bbox
height=1., # height : 1 inch
loc=3)
Update: As Kuti pointed out, for matplotlib version 2.1 or above, you should change the import statement to:
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
There is now also a full example showing all different options available.
From matplotlib 3.0 on, you can use matplotlib.axes.Axes.inset_axes:
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2,2)
for ax in axes.flat:
ax.plot(np.arange(11),np.arange(11))
ins = ax.inset_axes([0.7,0.7,0.2,0.2])
plt.show()
The difference to mpl_toolkits.axes_grid.inset_locator.inset_axes mentionned in #jrieke's answer is that this is a lot easier to use (no extra imports etc.), but has the drawback of being slightly less flexible (no argument for padding or corner locations).
source: https://matplotlib.org/examples/pylab_examples/axes_demo.html
from mpl_toolkits.axes_grid.inset_locator import inset_axes
import matplotlib.pyplot as plt
import numpy as np
# create some data to use for the plot
dt = 0.001
t = np.arange(0.0, 10.0, dt)
r = np.exp(-t[:1000]/0.05) # impulse response
x = np.random.randn(len(t))
s = np.convolve(x, r)[:len(x)]*dt # colored noise
fig = plt.figure(figsize=(9, 4),facecolor='white')
ax = fig.add_subplot(121)
# the main axes is subplot(111) by default
plt.plot(t, s)
plt.axis([0, 1, 1.1*np.amin(s), 2*np.amax(s)])
plt.xlabel('time (s)')
plt.ylabel('current (nA)')
plt.title('Subplot 1: \n Gaussian colored noise')
# this is an inset axes over the main axes
inset_axes = inset_axes(ax,
width="50%", # width = 30% of parent_bbox
height=1.0, # height : 1 inch
loc=1)
n, bins, patches = plt.hist(s, 400, normed=1)
#plt.title('Probability')
plt.xticks([])
plt.yticks([])
ax = fig.add_subplot(122)
# the main axes is subplot(111) by default
plt.plot(t, s)
plt.axis([0, 1, 1.1*np.amin(s), 2*np.amax(s)])
plt.xlabel('time (s)')
plt.ylabel('current (nA)')
plt.title('Subplot 2: \n Gaussian colored noise')
plt.tight_layout()
plt.show()