The world’s leading publication for data science, AI, and ML professionals.

Interactive plotting the well-know RC-circuit in Jupyter

Another step into ipywidgets and matplotlib

Remember to follow me using the "Follow" button on the right → : you’ll get notified for new articles, and help reach my goal of 100 followers 🙂

One of the most known and taught example of a first order differential equation is that of the RC-circuit. While it probably brings back bad memories from high school, this differential equation has a not-so-complicated analytical solution that we can explore easily using interactive widgets together with matplotlib.

Since this month (April 22), Medium decided that you have to have at least 100 followers to get retributed for you work. If you like this article, it would mean a lot to me if you just pushed that "follow" button 🙂 Many cheers, I hope you enjoy this article !

Photo by Harrison Broadbent on Unsplash
Photo by Harrison Broadbent on Unsplash

And yes, even not-so-complicated mathematical expressions are often hard to grasp : what happens if I increase this ? what happens if I decrease that ? This post is about helping our brain to make sense of analytical equations and numerical applications.

Ipywidgets allows you to interactively control values through widgets like sliders and buttons, making it super easy to understand how you analytical model behaves with respect to its parameters.

We will see how to write a class for an InteractiveRC that exposes a nice interactive interface, with a plot and its sliders.

If you are not interested in the physical developpment of the equation and its solution, you can skip the next part.

Also, this post follows a previous post on ipywidgets where I showed how to visualize noise decomposition using 3D vectors, check the embedded gif for a spoiler :

Use ipywidgets and matplotlib to visualize noise decomposition in 3D: this is Pythagorean


The RC-circuit : Setting the equation and its solution

Using wikipedia’s words : "A RC-circuit is simply an electric circuit composed of resistors and capacitors. It may be driven by a voltage or current source[…]". In our case, we will consider an ideal voltage source E.

The circuit looks like this :

Image by author
Image by author

We now recall the basic electronic equations that let us set the RC differential equation. Given that the current that flows throu the capacitor is

Image by author
Image by author

with q being the electrical charge in the capacitor. On the other hand, the charge in the capacitor’s bounds is given by :

Image by author
Image by author

Applying Kirchhoff’s Voltage Law, we get :

Image by author
Image by author

Given that the resistor tension is

Image by author
Image by author

We get replacing this expression in Kirchhoff’s law :

Image by author
Image by author

Letting the time constant tau=RC, we get the canonical form of the differential equation:

Image by author
Image by author

Now this is our first order, linear, and non homogeneous with constant second member, equation. The solution is of the form:

Image by author
Image by author

where A, and B are constants. By evaluating the solution equation at time 0 when the initial tension is, say, u_0, we get:

Image by author
Image by author

And evaluating at time "infinity", the capacitor’s tension tends toward the source tension E, so :

Image by author
Image by author

Finally, the solution we will plot is:

Image by author
Image by author

Just few words about this equation :

  • at t=0, the tension is equal to u0
  • at t=oo, the tension tends toward E
  • at t=0, the slope is equal to -(u0-E)/tau, and the slope intersects E at time tau (take the derivative and evaluate it at t=0 to convince yourself).

These are important facts about the solution that we will want to emphasize on our plot, again to help our brain get convinced about those usefull facts.

Interactive exploration of the solution

Now come the interesting part of "feeling" how the solution behaves based on the 3 parameters : source tension E, initial tension u0, and time constant tau.

We will use ipywidgets sliders to control the value of each parameters, and Matplotlib Lines to update the plot accordingly. We will use a class structure to nicely organize our code.

We start by creating an Output widget that hold the figure and ax, as well as 3 sliders to control the value of our parameters. We also add a slider to control the "time-span" we want to plot the solution, in terms of numbers of time constant. Then we set up the plot with the init_plot and set the limits and axis labels.

Then we will write an _update callback that will be the function that is called at each slider change to update the plot. We will come back to this function in a minute. Then we put everything in a ipyw.Hbox: the sliders and the plot. We also define a __repr__ helper function to easily display our plot and widgets.

We add some property to our class to access directly the sliders value with a nice syntax : self.u0 will return the u0_w slider value – same goes for E, tau, and n_tau. We also add a t_sample property that falls back on the n_tau slider value to create the time samples we will need to plot the solution function.

Now we want to plot 4 things :

  • the solution function tension, u(t)=(u0-E)e^(-t/tau)+E
  • an horizontal line delimiting the initial tension u0
  • an horizontal line delimiting the convergence tension E
  • a segmented line that emphasizes the slope at origin and the corresponding tau value in seconds

So we add 4 methods to generates the data needed to plot these lines.

Time to fill the init_plot function we used earlier. We will do 3 things :

  • plot the lines : u, u0, E, and slope at origin
  • add some text object to make our plot even more explicit
  • add a grid and a tight_layout to the ax

    Notice that when plotting, we use the data methods we just created to send the Xs and Ys to the plot function. The returned Line object references are stored so we can update their data later. Same goes for the Text objects.

Finaly, we have to go back to the callback function _update defined in the constructor method. Remember, this function will be called each time a slider changes its value, so we have to update the plot accordingly.

For each line, we need to update the line data, the text position, and the text’s text. Again, we make good use of the data helpers and the slider wrapped properties.

Show time

Now we create an instance and let the magic do rest:

You should get an interface like this one

Image by author
Image by author

And playing with the sliders will update the plot:

Image by author
Image by author

We can now play with our Model and better "feel" how each parameter affects the tension at each time.

We can visualize few things graphicaly :

  • increasing the initial tension u0 "shrinks" the curve verticaly, leaving the convergence tension unchanged at E. The "speed", represented by the steepness of the slope at origin, at which the tension reaches E also decreases when we bring u0 closer to E. This can be seen analyticaly by computing the derivative expression of the solution tension u.
  • increasing the source tension E "expands" the curve verticaly. The initial tension is unchanged, so the slope at which the tension reaches E from u0 is increased.
  • increasing the time constant tau "expands" the curve horizontaly : the curve has the same shape, but is "stretched" in time. The initial tension and convergence tension remain the same.
  • regarding the number of time constant the tension is plotted : we can see that after five or six time the time constant, the tension is pretty close to the convergence tension E. This can be proven analyticaly by evaluating the solution equation at time t=5tau for example.

Again, everything you’ll see graphically is based on the solution equation, so it can be proven analyticaly, which is nice and a good exercice to keep your math skills alive.

But being able to visualize the changes is also pretty rewarding, helping your brain to visualy grasp the impact of each parameter.

If you liked this post, remember to clap and subscribe ! More interactive posts are coming.

PS : if you don’t want to deal with the matplotlib objects and go straight to an interactive plot, checkout mpl_interactions.

Full code


Related Articles