Now, in previous versions of Matplotlib, we would use a backend style for Jupiter called NB Agg. But things have changed and now we use an inline backend engine. Now, you don't really need to know all of the details of this, but it's helpful to know that you can investigate this if you want to. Let's import Matplotlib and check which backend we're going to be using today. Here I'm going to import Matplotlib as MPL, and then I'll just run get backend, and you see it tells me which module I'll be using. Today we're using this backend inline module, which is the normal one that you would use in Jupiter right now. We're going to start our plotting journey by making a graph using the plot function. Upon this two axis an x-axis along the bottom and a y axis which runs vertically. First, let's import the pyplot scripting layers PLT. All of the functions which we're going to run against the pyplot module are part of the scripting layer of the architecture. Let's take a look at the plot function by looking at the docstring. Here I'll just import as PLT. Remember, we can look at the docstring of any function we want just by adding a question mark afterwards. Now, when we run this command, Jupiter is actually going to go and look up that doc string for us and show it here. You can see this is the method signature, plot.plot, and we've got a star args, scalex, scaley, and we see this star star kwargs. Then it gives us whatever the developers have written here for the docstring. For this one, it's actually quite extensive and it mirrors what you'd find in the online documentation as well. That's a lot of documentation. If you're not used to seeing it, this Python function declaration with two arguments, the star args and the double star keyword args can be a bit obscure. What's being said here by the star args is that the function supports any number of unnamed arguments. The double star keyword args also means that it supports any number of named arguments. This makes the function declaration very flexible since you can pass in basically any number of arguments named or not. But it makes it difficult to know where there's an appropriate argument that you should be using. Reading on, we see that the arguments in this case are going to be interpreted as x, y pairs. Let's start there. Let's try with just one data point at position 3, 2. The return value is the plot itself. Jupiter lab is going to actually display this automatically on its own and render it in the notebook. We don't see any data points though, which is a bit odd. It turns out that the third argument to plot should be a string, which signifies how we want that data point to be rendered. Let's use a period. This means a dot, and we'll see that our data point now shows up. The dogs tell us what the different characters will render like. Here we're just going to use this full stop or period for the marker. You'll notice that the subsequent calls to plot have not updated our previous visualization. The backend that we're using is not interactive, so these subsequent calls create new plots as new cells in the notebook. This is a handy way to iteratively explore your data. Here's where some of the confusion with Matplotlib as a library tends to come from. In the last lecture, I explained that there's this artist layer and then it has figures with subplots and axes and data points and they're all rendered as patches onto these axes. But we haven't actually seen any of that here. Instead, we just got one function on a module named plot. What's going on? Well, the pyplot scripting interface is managing a lot of these objects for you. It keeps track with the latest figure of subplots and of the axes objects. Moreover, it actually hides some of the details of these methods on its own. The Pyplot module itself has this function called plot, but as redirecting calls to this function to the current axes object. This makes for a significant learning curve and you'll see many discussions in web tutorials and on StackOverflow where people are confused about these two different approaches to make figures show up. In data science workflows, I think it's much more common to use this scripting layer like we just did. But it's worth it to take a moment at the alternative object oriented approach that's a bit more verbose. Actually, well, some would call this the Matplotlib object API. I think it's more accurate to actually think of this as directly interfacing with the artist layer instead. I'm going to do a little demonstration here. First, I'm going to import a new backend called the FigureCanvasAgg and then bring in the figure object. This is the top-level object that we're going to be using. I'll just create a new empty figure and you can just call figure with empty parentheses. Then I'm going to associate this figure with the Canvas backend. I can do that just by calling FigureCanvasAgg and passing in the fig. Then we can add a subplot directly to this. We're going to talk more about subplots in a future lecture. But this number here, this 111, that actually just means that we want to add one plot. The return value for a subplot is the axes object, which contains methods for plotting and we usually call that ax. You'll see that that's pretty common. Now, we can actually get to plotting and we can plot on the axes as per usual. We just call ax.plot and we pass in the parameters there. Then finally, we have this figure, but our back end isn't actually able to render this directly within Jupiter Lab. Remember, our back-end here is this FigureCanvasAgg. We actually have to save this to a PNG file, a ping file. I'm just going to call canvas.print_png. After you execute that, you don't really see anything. All these objects have been created, but they haven't been rendered anywhere except for in a file. What we could do is use this quick HTML cell magic and execute that to see the rendered image. This is a lot more work than using the scripting layer, but you can see here that the effect is the same. To use an HTML cell magic here, we just put percent percent HTML at the beginning of the cell, and that tells Jupiter to render the rest of this code as HTML. Here, I'm just saying create a single image element and render it. We can see that that image is exactly the same as our previous one. It's important to note that the scripting layer isn't magic, it's just doing some of the behind-the-scenes work for us. For example, when we make calls to pyplot's plot, the scripting layer actually looks to see if there's a figure that currently exists and if not, it creates a new one, and then it returns the axes object for this figure. We don't have to store any of that though because we can always get access to the current figure using this GCF function, which stands for get current figure. Similarly, we have another function called GCA, get current axes, which will return to us the current axes to render upon. Let's create a new figure with pyplot, grab the axis, and set some x,y limits. Just as we did previously, I'm going to call plt.figure. This is going to create a brand new figure object for this cell. Then I'm going to plot here 3, 2 that point, and this time, I'm going to use a circle marker just to show you how this syntax changes. Now, if I want to get access to the axes there, I call plt.gca, that's going to get the current axes of the current figure and return it. We usually call that ax. Then I'm going to set some properties of that just for a demonstration. The function that I'm going to use is called axis. There's a lot of, by the way, axes, axis in this lecture, so hopefully, you'll be able to follow here. But this function actually takes four parameters, a minimum value for x, which we're going to put a zero, a maximum value for x, I'm going to put that as six, and a minimum and maximum for y values. We can see here that the dot now is rendered, it looks a little bit different, and we can see, if you look back, your axes values for both the x and y have been constrained. One more demonstration on the fundamentals of putting together a plot. You can add artists to an axes object at any time. Pyplot is actually doing this for us when we call the plot function, it's determining what shape we want from the string, the location associated with that shape, and it's creating a patch object and adding that to the axes. If we make subsequent calls to the plot function before we render it, the data is actually going to be added as a different series and colored appropriately. I'm going to create a new figure. I'm going to plot one point here at 1.5, 1.5 with the circle marker, and then I'm going to add two more points right underneath. I'm just calling them subsequent calls to this plt.plot. You can see here that we now have three different points all in a line and that our axes are constrained to fit this data. A lot of complexity is hidden from you, but you can go even further with the axes object to the point where we can actually get all of the child objects that the axes contains. We can do this with this get children function. I just want to show you what this looks like because I think it's pretty interesting to know that this exists even if you're not going to be using it all that often. If we want to get the current axes of the current image, we can say plt.gca. In this case, a new axes object is being created, this is a new cell. Then I'm going to add a point at 1.5, 1.5, and then I want to take a look at that axes and see what all of the children look like. You can see that for this image, we actually have a number of things: We've got a Line2D, a bunch of splines, an XAxis, a YAxis object, and you can look up every single one of these in the documentation. In this case, our Line2D object contained in the axis, this is actually our data point. We also have these splines which are actual renderings of the borders of the frame, including all the tic markers, two axes objects and a bunch of texts which are the labels for the chart. There's even a rectangle and that's actually the background for the axes. That was a whirlwind tour of how to be productive with Matplotlib and make your first chart. Now, in truth, you're not going to spend a lot of time getting individual artists, or interacting with splines, probably. But you can, if you want to, the system isn't magic, and we've walked through how you can investigate a bit better to understand what's actually happening underneath. In the next lecture, we're going to go through some of the different built-in charting options which are available to us in Matplotlib.