Well, if you know my unit, you know that we use Plotly most of the time for Interactive Plotting, but there's always Matplotlib. Matplotlib is the grandparent of all Plotting libraries in Python and it's really, it's a beast of a piece of software. There's, you know, you can do any kind of plots with Matplotlib. So what I'm going to do here is 80 minutes put as much of Matplotlib into 80 minutes as I humanly possibly can and show you how to use it. Here we are in JupyterLab and we've opened our Matplotlib tutorial.ipynb file. What I do like to do is to keep my table of contents open on the left hand side and I also like to keep this simple setting there just to save a bit of screen space. So there, Matplotlib tutorial for scientific plots. Now I want to tell you something first and if you've never used Matplotlib before, you've got nothing to hang this information onto, but I want to keep it in the back of your mind. So when you start using Matplotlib, you know what to do and that is the default setting. So you can actually set some parameters and save their values so that every time that you create a plot, you know, these defaults will be used. We can set that class rcparams while we code or you can look at this file here matplotlib rc and you can find out where this file is by importing matplotlib and then calling the matplotlib underscore fname function. And if you do that, you'll see where this file is and you can tinker around with that. Just don't mess things up, I suppose. So as I said, you've never used Matplotlib before. You're not quite sure what this all is, but sometimes when you do want to generate the same sort of type of plots, you want all sorts of default settings. You can just play around with matplotlib rc or the rcparams class. And I suppose in the beginning of a notebook or some code, if you use VS Code or PyCharm or whatever you use, you can set that with some Python code as well.  Just remember that you can set a bunch of default values. So let's have a look at the table of contents. These are all clickable links and it takes us to the different parts of this notebook, but we can also look down all the way down here in our table of contents. A bit of introduction. We've already had that table of contents, we're talking about now. And then packages used in this notebook, we'll run through that. Now there's two basic interfaces, there's more, but the two main ones that we can use is the Pyplot interface. Of course, back in the day, it was trying to look like Matlab, which I suppose we don't have to do anymore, but that was it. And you can use the Pyplot module and make your plots or make the code at least very similar to Matlab. And then there's the object-oriented interface, which you'll use most of the time once you get used Matplotlib for sure. But we're going to start with the Pyplot interface, just do some basic plots there, lines, plots, line plots and scatter plots, some frequency plots, etc. Then we're going to tackle this object-oriented interface that allows us much more control. And I think you'll love that a bunch more. And then because this is Matplotlib for scientific plots, we're going to look at some plots for functions and vectors. We're going to look at contour plots, quiver plots for vector fields and then stream plots for vector fields as well. And then I'll just show you very quickly how to save your plots if you want your plot that you've worked so hard on, ready to be printed in your report or published on the web, etc. Save your plots as PNGs, JPEGs, etc. So let's quickly look at these packages that we can use in this notebook, us, just so that we can interface with the folder structure on our computer, symbolic Python, because when we talk about the vector fields, I'll show you how easy it is to take partial derivatives, just using symbolic Python, the friend that we have to use all the time, NumPy. And then the Pyplot module here, Matplotlib. So import matplotlib.pyplot as PLT, so using that namespace abbreviation, well, NP and SYM as well, namespace abbreviations that you'll see all over the show. And then to take ultimate control over how we put a bunch of plots in one figure, we'll use the grid spec module. So import matplotlib.gridspec as grid spec. And because I'm recording this on MacBook Pro, we'll just set the inline back-end figure format there to Retina to have the high DPI plots displayed to the screen, so they look a lot crisper. Now you can set your themes, if you're into that sort of thing, set your themes. And so plt.style.available, the available attribute there. And you can see the bunch of styles that we can use now. I just wanted to warn you, if you've got to have a tick installation on your machine. And you've got to have science plots. You've got to have that package installed as well to see all of these. If you don't have, there'll be a subset of these module, I should say these styles available to you. And we're just going to stick with the default here. I just want to show you that you can also tinker with the back-end that matplotlib uses to do create these actual plots. And you don't have to be too concerned about that. I'm just showing you here, I've set the back-end to macOS 10. And so you can read up on all these things, little bits of information as you start getting used to matplotlib.  I'm telling you about all of that. Depending on your coding environment, what you're using, you might have to run this magic command matplotlib inline. You might not have to. But Sydney here, it's just going to allow us to plot, generate the plots inline with our code. So quick introduction here to the notebook. Let's get back. And we're going to just use the piplot module to generate some basic plots. Quick plots for the piplot interface. So there we go, line plots and scatter plots, which are basically the same thing, depending on how you set up the plot. First of all, it's a plot. It's got two axes and x-axis and y-axis. It's a Cartesian plane. And we've got to have x-coordinates and y-coordinates. So what we're doing here is just generating some values for ourselves to plot. And I'm going to use the computer variable names x-values and then y-values underscore one and y-values underscore two. So those will be my x and y-coordinates. And I've got two different sets of y-coordinates for the same set of x-coordinates. And I'm using the lint space function from numpy there. It has a start value, a stop value, and then how many points you want, how many values you want for that array that it's going to create. And you can think of the array just as a vector of values for your x-coordinates and then your y-coordinates. So we're going to start at zero and at four pi. So numpy dot pi for the irrational number pi there. And we want 50 values in that interval. So zero is going to be included and of course four times pi exactly is not going to be included. And then what we're going to do is I've got these two arrays and I'm going to add them to each other. So the first one is the sign of each of these 50 values. And to that I add element-wise, this second array that also contains 50 values. And it is 50 values because I'm passing x-values to the lint function. So that's going to give us this 50. And what I want is 50 values from the numpy random module and the random n, that standard normal distribution, mean of zero standard deviation of one. And all I'm doing is just multiplying each one by 0.1. So that's going to broadcast to every element in this 50 element array. And I'm adding this 50 element array to this 50 element array. So that one to that one. So we're just adding some random noise to the sign value of each. And I'm doing it again for y-vals underscore two. And because I want to draw two plots basically, or two figure, two sets of information in this same figure. So that's basically the plot function in the pi plot module. So plt, that namespace abbreviation we had for matplotlib.piplot, so .plot. And all I'm passing is this array of x coordinate values and the array of y coordinate values. And that's all I'm doing. Well, I've added a little bit there. I've added a semicolon. If you use a notebook like this, there's some other information that matplotlib generates with these plots. And that's going to be printed to the screen as well. And you can just suppress that by using the semicolon. And I don't have to put plt.show because in the Jupyter environment, that's going to be done for you. So if you've seen plt.show everywhere, you certainly don't need to do that. And here we go. We see the raggedy little line here. Sort of, you can see the sine wave coming out for every x value. And we see we're going from about 0 to about 4pi. So there's just over 12 there towards 13. But I've only got 50x values in that interval. So you can well imagine what's happening here is there's some interpolation happening. So there's just these little straight lines drawn in between each of these 50xy coordinate points. So that looks a bit ugly and we can certainly do a lot more. So we're imagining that these are values, perhaps it's over time, and some independent value depending on what time is. And we've ran the experiment twice. So let's get going. Now you can see here, this is the code that we can use for our first plot over there. And you see I'm using plt.plot, plt.plot, and then all sorts of other things, legend, x label, and each one of them take a bunch of arguments and keyword arguments. I'm just going to use the word argument. I won't specify when something is an argument and keyword argument, but you know there's the difference between the two. Remember keyword argument, you actually have to use the argument's name. That's a keyword argument. And then with the normal argument, you can just pass the values. Anyway, there's a bunch of these arguments for each of these functions. And for some of them, I just want to use the same value over and over again. So I'm just defining them as variables here, assigning them to computer variable names. So I'm going to have one called marker underscore type. And you see I'm assigning a string to that. And it's a lowercase o dash dash. And that's going to be the type of marker. And it's a shorthand notation for making my markers into round little circles and my interpolation making those dashed lines. Simple as that. I'm defining two colors. And I'm using actual color names as strings. One is Dodger blue and the other one's orange red. And I'm assigning that to color underscore one color underscore two. I'm assigning the integer one to this computer variable LW six to the computer variable MS. And then these two strings to two more variables label underscore one label underscore two. So what I'm going to do in this tutorial, I'm just going to run this code plotting the plot, and you'll see what it looks like. And then we'll go line by line to see, you know, what happens. So there we go. Beautiful plot. Lots of information that you can clearly see that we have these 50 values. It's two colors there. And it clearly shows in the legend that that would be, you know, data from two experiments, experiment one and experiment two. So we ran this twice. And those were the results that we calculated. You can see a title at the top position over time. You can imagine that this was a type of experiment that generated a position at different time points. So on the x axis, I have an x axis label that time and then I have units then square brackets micro seconds. So you see a little bit of tech code there, the micro symbol. And then on the y axis, I have a label position and the units CM centimeters. So how did we generate all of this? Oh, by the way, you can also see the gray grid there, all sorts of things. So let's see how we generated this. The first thing we did, line number one here, plt.figure. So a figure in matplotlib, that's the blank canvas onto which you plot things. And we get to the object oriented interface. We'll see that each one of these things are called axes. So this is an axis on a figure. So the figure is this blank canvas. And then we have all these axes on different axes. And then when we use the object oriented interface, we'll see we can do more than one plot, you know, on the same blank figure canvas. Now I'm only using one of the arguments here. Now remember always here, it's easy here in JupyterLab. I'm holding shift tab when I'm inside of where inside of the function there, where I would place my arguments, shift tab, and it's going to give you the help section. And you can see there, num, fix size, dpi, face color, edge color, frame on, figure class, clear, and then a bunch of other keyword arguments that you could do. And I'm only using fix size here. So that's going to give me an inches, 10 inch by 6 inch. So depending on the dpi, when you save this and print it out, your mileage is going to vary regarding how big this figure is actually going to print out if you do go to print. But on the screen here, 10 across and 6 up. So it's width and height, you know, sort of nice enough for us to make a video recording of, see what's going on. So it's a tuple that we assign to this keyword argument, fix size. And then plt.plot, plt.plot. So you can see in the same figure, I'm calling it twice, you know, one is going to be the blue set of data and the other one the red, orange, dodger blue and orange, red, I should say. So the plot, as we did with the bare bones one, it's x, y, and y, that's all we're going to do. That's the two sets of arrays for x and y coordinate values. And that's going to be, of course, all the markers that you can see here, not the interpolated lines, because there's only a 50 on this little interval.  And then dash dash dash minus minus, that'll be this dashed line. And then color, keyword argument color, I'm sitting there to color one, remember that was dodger blue, that was a word. So it's saved as a string. So there are many colors that are actually named colors. LW, I'm assigning that keyword argument to this computer variable LW. And to that, I've assigned the integer one, so line weight is one. MS is the marker size. So that's going to be six there, because we had a six up there. And label equals label one, label one is experiment one. So if I put a label value there, and we see here is legend, if I use the legend function, it's going to draw to create this little legend here, experiment one and experiment two, it's going to use these values that you assign there. So I'm doing it again for y vales two, and the second color, no problem. So the legend function then, I can place it in certain parts. You can, there's lots of granularity here, but the common ones are upper right as strings, upper right, upper left, bottom right, bottom left and center, I think there's as well. So, but there's more granularity about exactly where you want to put it, but we'll get to that. And this one I'm putting in the upper right, and I'm setting a fun size. So once again, let's just go right at the start, hit shift tab, and you can see there's all the things that you can do there with the legend, all sorts of things there. So at the moment, all I've done is the location and the fun size, and then the X label. So you see, I've got a bit of tech in there. So there's a subset of tech in metal lip that you can use. And the way that we're going to do that is pass a raw string. So there are there. So that is just going to ignore, you know, escape characters, etc. But that'll still read all of my latte code here, which goes inside of a set of dollar symbols. So left backslash left, and then the left square bracket, you know, that opens the square bracket, and it'll size it appropriately. Otherwise, you could just use the left square bracket, but then it won't be sized. Backslash Mu, that's new for the micro symbol and S. And then the right square bracket. So that gives me time, as you can see at the bottom time, and then the units microseconds. The Y label, as we can see there, I'm just giving that a fun size. And then it's this position and centimeters. And then the title function, I'm giving that a string value, position over time, and a fun size. And with title as well, it's just a shift tab, there's a bunch of things you can do. And then this font to dict, I mean, I just put fun size there, but you can put a lot of things there, and you can place them all in a dictionary and assign that to the font dict keyword argument there.  The grid is going to generate this gray grid in the background, and that's always good to see in these scientific plots. And then the tick, tick params, so plt.tick underscore params. So you'll see this, the values on the X and Y axis, 0, 2, 4, 6, 8, 10, 12 on the X axis, minus 1, minus half, 0, half, 1 on the Y axis.  Now those are major ticks, you also get minor ticks, smaller ones, and you can set how long they are, and their color, and all sorts of things you can set. But here I'm just using the witch argument, I'm sitting there to both, so that's both minor, major, minor axis, tick marks, and I'm setting the direction to in, there's also out, and some other ones, and that just means they point inwards into the axes, instead of pointing outwards towards the numbers. So I like to do that, sort of like, this looks a little bit better. So there you go, it's a bunch of stuff, and that's what we're going to do in this tutorial. So I'm just going to generate these plots, and they'll have different keyword arguments, different arguments, different functions for mapplotlib, different ways of setting up the plot, and that's how you learn, that's how you learn. So you can see there, the color, we said dodger blue, I think, and red, orange, but there's also these little shortcut colors, k, w, r, g, b, c, m, y, and that's for black, white, red, green, black, white, red, green and blue, and cyan, magenta, and yellow. You can just specify a value, so color equals, and 0.5, so on that interval 0 to 1, that's just simply going to give you a shade of gray, or you can use hexadecimal colors there, so color equals, and then as a string, pound symbol or hashtag, and then the sets of three sets of two values there, to give you the intensity of your red, green and blue pixels there, so you can set a color, any color that you want. Great stuff, and the next one we're going to add a model to our data instead of that interpolation, so I'm just going to generate the plot, so you can see what's happening here. So what's different here? First of all, we don't have the interpolation between our data points, instead we think that this is the model for our data, so it's this little sine curve obviously that we just put in there, but now the legend is not, if we look back up here, experiment one and experiment two, they were written as two rows in a column, here we have a single row with three columns, and we printed that way, so that's one little difference. So first we just generated these values for our XY coordinates to create this model, the sine curve there, so I'm just lint-space again from zero to four pi, but this time I'm just ramping it up from 50 points on my x-axis to 200 points, so that gives me a little finer detail, and when the interpolation happens so that you draw a continuous line as you would do taking a pencil to paper, so I'm just putting more in there, just gives me a lot of more to work with, and my model we're just saying well that's the sine of all my x-values. So, fixed size, we put there plot x-values, y-values one, and this time I'm not using dashes, I'm just saying just a lowercase o, so that is just going to give me these round markers, still same color, same size, still same label, so nothing's changed there, so I'm adding a third plot there, that's x-values underscore model, these are the ones I've generated up here, and then just a dash, a single dash, that means a straight line, so interpolate with a nice, with a nice line, and because I've got 200 points on this interval, it's going to look you know quite smooth, and then the label that I give it so that the legend function knows what to do, so the legend function again the location, the font size, but now I have n call, and I'm setting that equal to three, now so it means you know I have three columns for my legend, so all three of those labels, because I've got one label, two label, three labels, each going to go into one column in a single row, so that's how we got that, our labels are still the same, and what I've done here is a new one, y-lim, so the y-axis limits, and I've used the top argument then, I'm setting that to 1.5, so it's going a bit higher, and the reason why I did that is just because I have this legend here on the top right, and it can encroach a little bit on the data itself, or your model, or whatever you're plotting there, so if you can set that a bit higher, or but you can also do x-lim of course, and do bottom, and left and right, etc, just so that you give yourself some extra room, so that would be, you know you've got to think about these plots, not just use code, and the same sort of generic code all the time, you've got to look at what the plot is, and sort of change things accordingly, and I'm putting the grid in, and I'm doing the same with the tick parameters, so without these, the interpolation of course, if we take away the model, this is just a scatter plot of x, y coordinate values, so let's do a little bit of that, I'm creating two sets of values again to erase in-depth and depth for independent and dependent variable values, I'm using rand int there from the random modules, so random integers from on the interval 100 to 300, and 150 of them, and then each one of them by broadcasting I divide by 2, and then my dependent is just going to be times 0.8 times a bit of random noise there once again, but this time it just comes from a uniform distribution of the values in this interval negative 10 to 10, so let's see what this looks like, this is a scatter plot, and that's just because, you know again it's just that O that I'm doing on the plot, so still the x values, the y values, and then the type of marker, so there's no dash there, so it's not trying to put a line in there, it's just the actual markers, I've got a title, x label, a y label, no problems there, and then the grid I've changed up a little bit, so I'm saying grid equals true, so this time I'm using the true argument there, and then I'm setting a color, so if I set color 0.5, remember that's just going to give me scales of gray, so that's like 50% gray there, and then I'm defining what the dashes look like as a tuple, so it's line space, line space, so I want a line length of five, then a space of length two, then a line length of one, and then another space of two, and then it'll go to the front again, line space of five, so you can see these long dashes, short dashes, long dashes, short dashes with a sort of two points in between each, so you can really define exactly, you know, what your grid is going to look like, and there's lots more granularity if you care to look that up, so that's great stuff, but there's also the scatter function here in the piplot module, so what I'm going to do here is create two more independent variables, and they both come also from uniform distribution and 50 values of each, because on a scatter plot you can actually have information about four variables, so let's run this code and see, we have a different marker size and we have a different color, so we're using plt.scatter instead of plot, I still have my x and y coordinates, the size now, s equals, that's these values up here, so each one of them will have a different size, and then c for color, they'll each have a different color, and I'm just setting some transparency there with the alpha argument, alpha equals 0.5, so that's four numerical variables that are represented by this scatter plot, great stuff, now what we've seen up till now is that both our x and y axis are linear, but we can also use other scales, so what we're going to do here is just do the log scale, so I'm going to create a computer variable here, vales for log, vales underscore four underscore log, and I'm using some less comprehension there, so I'm saying 10 to the power i for i in range 10, so it's 10 to the power zero, 10 to the power one, 10 to the power two, up till 10 to the power nine, and then we're going to plot that, so let's have a look at this, and what we can see here on the y axis, that's the log base 10 scale, 10 to the power one, well 10 to the power zero is down here, 10 to the power one, three, five, seven, nine, and we have a linear scale on the x axis, so how did we do that? I've still got my figure there, I've got my plot, and what I'm saying is vales for log, so all I have here at the moment is just one set of values, remember we had x coordinates and y coordinates, if you just put one set there, it is going to do, take those as the y coordinates, and what it's going to do is just going to do zero, one, two, three, four, five, six, seven on the x axis, so it's going to say it's point the first value on that, this y is essentially going to be the y coordinate values, the first one is at exposition zero, the second one is at exposition one, then two, then three, then four, so that's what's going to happen if you just put those in, and of course you can see there, there's a mark and a dashed line, you know how to do that now, and I'm sitting specifically that my y scale is log, so plt.y scale, and I'm setting that to log, so it knows and the default is log base 10, and then as per usual I'm using a bit of LaTeX there, you've seen how to do that, there's a raw text as well, you can do either of those, I'm putting in a grid, nothing else different, so that'll be that log scale, what about if we want to do the same for the x axis, so let's have a look at this, there we do, there we go, so I'm now saying plt.x scale is now log, so it's going to put that log values on the x axis for me, and you've seen what happened to the y axis now, that is this again 0, 1, 2, 3, 4, no problems there, what about different log scales, so my x coordinates is going to be base 10, and my y scale is going to be base 2, so I'm just generating x and y values there, let's have a look at the plt, and you can see it's still a straight line, because on the x axis here I have log base 10, on the y axis I have log base 2, so how do I do that, I use the semi-log x and semi-log y, the default is base 10, so I don't have to put anything there for the x axis, but for the y axis I put the base as 2, and that's going to give me the space 2 values, so we do have values, you know, which definitely will not give us a straight line on the Cartesian plane, but now I have different log scales there, and I get my straight line, if both of them have the same base, so let's generate some values there, both base 10, I can just use the plt.log log, and that'll do both of the axes, and I set a base there, base 10, so now we have them both as base 10, and still our straight line there, so that's how to deal with the log scale, so that's it for lines and markers, you know scatter plots, let's move on to frequency plots, now we can do both the continuous numerical variable and categorical variables, when it comes to frequency charts, if it's continuous numerical we'll talk about a histogram, and if it's categorical variables we just count the frequency, that's going to be a bar plot, although we can also use the sort of mean and errors error bars when it comes to bar plots, let's have a look, so frequency plots we're going to start with a histogram, so we're just generating two sets of values here, two arrays, I'm going to generate a thousand elements in this array from a normal distribution with a mean of 100 and a standard deviation of 10, and the second one with a mean of 98, standard deviation of 15, so I'm using numpy to generate those random variables for me, and then we're going to use the hist function, plt.hist, so let me show you what it looks like, and I'm not using the semicolon because I actually want to show you everything that gets generated by this function, so the first thing we have is an array, 62767151, and that's the height of each of these bars in my histogram, and you can see that it's a continuous numerical variable because there's no gaps between the bars, so what happens with a continuous numerical variable, of course there's binning, so there's a lower and upper limit for each bin, and we're just counting how many of our 1000 values fell into that little interval, and we can see in our first interval there were six values in our second interval, 27, third one, 67, that's what it does, the second array that you can see there, that's actually the limits, the intervals of these bins that went from 68.4496 to 74, so that will be the interval of this first little bar here, and then the second interval, so you can see what Matplotlib decided to do by default to generate the intervals for these bins, so that's quite important, now that's an ugly histogram, so we certainly do a bit better, one thing we might want to do and say, well depending on our data, it might be more natural to have bin sizes that are a bit different, maybe we want to go from 70 to 80, 80 to 90, 90 to 100, 100 to 110, so I'm going to do that with a bit of list comprehension there, create a computer variable called bin underscore intv for bin interval, as I said using this comprehension there, so it's 10 times i, and i is the range from 6 to 15, so that's going to be 60, 70, 80, 90, up to 140, if you think about that, and now I'm going to pass that to the, that that Python list to the bins argument, and there we go, so now we see these bins 60 to 70, 70 to 80, 80 to 90, 90 to 100, now let's do a little bit more, let's run the code, see what we get, and we can run through it, so that looks to me looks like a little bit of a better histogram, of course the text is a bit too big, the title and the access labels are too big, and the legend's too big, but you know, I want you to see it on the screen, so first of all you can see that we now have these sort of step function to show off our histogram, that looks a little bit better, we can see that we have for both experiments basically, we have the histogram for both sets of values, and we have our legend way off of the figure, it's away from the figure, so how do we go about that, we still have our fixed size there, we're using HIST, and of course we're using VAR underscore group underscore one, it was our first array, and I'm just setting the number of bins this time, so you can see there for the for this one group one here, you can see there it starts just below 70 and then goes here to about 74 point something there, but if you count them there'll be 10 bins, and all we can see with the step is the outside of all my little rectangles, making up the frequency chart the histogram, so I'm just stating I want 10 and what happens is map plot level look at the minimum, the maximum value, you know make 10 intervals and that's it, and how I get the step is by doing a HIST type and setting that to step, the string step there, I'm putting a label so that I have something for my legend function to do, so for the orange one though we're putting this bin underscore intv, so you can see that goes from 60 to 70, 70 to 80, the HIST type is still step, and the label is group two, now for the legend we've got one size equals 12 but too big, now we've got this b box to anchor and we see this tuple assigned to that keyword argument, and what we have here is the bottom left is 00, the top right is 11, so from 00 that's 0% to 100%, so we gain 1.05, so 5% over the maximum on the x-axis, and that's why it's over beyond the plot itself, and then 100% so right at the top on the y-axis, I'm saying frame on is false, remember there's this little frame around it, and I'm giving it a title, grooves, and you can change the size of that too because that looks a little bit small, and that's how you get sort of this kind of plot which starting to look a bit better, now bar charts is for counting, so let's create these four classes abcd, saving them as a python list, two categories, I'm going to do random choice of the classes 500, and that's with replacements, it's going to be ac, bbc, abd, db, etc, and I'm doing that twice assigning that, and now we're going to use the unique function in python, and that's going to give us back two things, the array of unique values, and we know where it came from because we generated those four, you know the four classes, and then we've got those returns, return underscore count arguments set to two, so it's also going to return the counts, so there were 130 a's, 121 b's, 117 c's, and 132 d's here in cat underscore group underscore one, so what I'm going to do now is just use a bit of indexing because I've got these, the tuple of two values, the two arrays there, so I'm just referencing array number one, that's the second one, so all I'm saving here is those values, 130, 120, 117, and 132, I've got my classes saved, so now I have these independent of each other, you know the abcd and the count of each one of those for both cat one and cat two there, so let's generate this figure and see, this is what it looks like, a very boring bar chart, and it's just a frequency chart, and my variable is nominal categorical, I suppose you could say it's ordinal categorical, but it's categorical nonetheless, abcd, and for group one and group two, I'm just showing you the count of each, so how did I do this grouped bar chart? Well it's plt.figure and then bar, plug plt.bar, now you've got to hang on in there because it's not so easy just to get these correctly aligned here at the bottom, because this axis wants to be numerical, it wants to count zero, one, two, three, four, and that's exactly what we give it, we say numpy.a range four, so that's going to be zero, one, two, three, and that's what we have there, abcd, zero, one, two, three, and I'm subtracting 0.2 from that, so it's going to be minus, so zero minus 0.2, so it's minus 0.8, and then the next one also subtracted, so one minus 0.2, two minus 0.2, and three minus 0.2, so this is actually shifted to the left, so these dark gray bars actually just shifted to the left of zero, one, two, three, four, then the counts, and remember these, those were those counts, 130, 121, and that gives us the height of these bars, giving it a label group, so for the legend, you know it has something to grab onto, and then the color I'm setting that to gray, bar two, I'm moving everyone over 0.2 to the right, and then the counts for the second one, and for both of these you'll see 0.4, 0.4, that's how wide things are, and because I've split the centers negative 0.2 to the one side and 0.2 to the other side, they're going to basically just line up very nicely with each other, so no problems there. Other than the fact that I still have, you know, zero, one, two, three, four at the bottom, which I have to change, and that's what I do with the x-ticks function, so again the x-ticks are going to be range four, or numpy.a range four, it's going to give you the array or list, doesn't matter, so that's zero, one, two, three, four, and then I replace that with the classes, that's a, b, c, d, so zero's going to become a, one's going to become c, and three's going to become d, so that I have a, b, c, d at the bottom instead of zero, one, two, three, four, clever. I have my legend, and again I'm sitting in call to two, so that it's like two columns there, horizontal instead of stacked, and I'm generating a bit more space at the top, so that these bars don't run into my legend there by sitting the y-limb, and that's how you would do that. Of course, you can use bar plots just for statistics as well for different groups, as far as a numerical variables concerned, so let's do something a little bit different. I'm going to say aluminum and copper, and I'm going to take from a normal distribution a hundred values of each, and you can see the mean there and the standard deviation there, from which these two sets of values are generated, and I'm just going to save the mean and the standard deviation of each of those arrays, so numpy.mean, numpy.standard deviation, remember this is a sample, not a population, so in our denominator there we subtracting one, when we calculate the standard deviation, or the variance first at least, so you've got to put ddof there, the degrees of freedom there is one, so that you calculate the sample variance, or sample standard deviation, and not the population standard deviation, but anyway, I've saved those two, and now what I'm going to do is the following, so let's just generate the plot first, and you can see what happens, so we have aluminum on the left-hand side, copper on the right-hand side, and this would be, say for instance, like coefficient or thermal expansion, and you can see the bars go up to the mean, and we're using the standard deviation as the error bars, so not confidence intervals or anything, we're using standard deviation in this instance just to keep things easy, and those were the two error bars, so how do we do that, the figure again, fixed size, nothing new, bar, nothing new, so again range two, so that's going to give me on the x-axis a zero and a one, and then here with the x-sticks remember I'm just changing those, I'm swapping out zero and one with aluminum and copper, or aluminum if you from certain parts of the world, so the height of the bars, I'm just setting that as a python list, so the mean of aluminum and the mean of copper, 0.4 again the width, and then y error, y error, that is what's going to do the error bars for us, and I'm passing the standard deviation of each of those as the list, align these error bars to the center, cap size is eight, that's the little horizontal bars there, the color is black, and that would be black for these, not the error bars themselves, but the actual bars of the bar plot, but I'm sitting in alpha value of only 10%, 0.1, so they like light gray, title and x-sticks we spoke about, and the label, and once again I've got a bit of latte code there to show the degrees, per degree Celsius, the coefficient of thermal expansion there, and we see for aluminum and copper there, of course I don't like bar charts for that, you can go, definitely go a bit differently, first of all what I did here is just a different kind of error bar, by not using error y error as we did here, not using it separately or as an argument inside of the bar function, but there is an error bar, plt.errorbar function itself, and I'm doing exactly the same as what we had before, but this time around I can say that I want a dot in the middle and I want a color, and so you can specify a little bit more about how these error bars would look, the way that I would do that though is just use the error bars on their own, I think this looks better, but it might be different for you, so it's just plt.errorbar, range of 0 and 1, so I still have aluminum and copper there, which I replaced by the x-sticks that you know about now over there, I still got a title there, y-label, put a bit more space on the top because this error bar was getting a bit close to the top, so I've increased the y-limb a little bit there, and then as far as the error bar is concerned again I can put a D as diamond before we had the O there, now I've put a D for diamond, so you can see the diamond there, and you can do all sorts of other things to improve the look of these, but that's certainly, you know, one way that we are sort of abusing a frequency chart to generate these or place these error bars. One more chart type that you see all over the show, not my favorite type of chart, the box and whisker plot, it's going to give us the same sort of information that a histogram is going to do for continuous numerical variable other than the fact that it's working with a quantile, so you'll have the quartile values here, and this is what it looks like, so let's see how we generated all of this, so if you don't know this bar or this box in the middle, I should say the lower end of that is the first quartile value, the upper one is the third quartile, you'll see if you look very closely there's two lines there in the middle, there's a little orange line that would be the median, and then there's this dashed line that will be the mean, and then the little notches at the moment at the set to indicate the 95% confidence intervals around the median, and we're using a bit of bootstrapping there to calculate the values there for those notches, so how do we go about it, plt.figure, nothing new, box plot is brand new, I want two sets of values, so when we did the histogram, var underscore group underscore one, var underscore group underscore two, so those were just the rays of values, continuous medical variables, I'm putting flyer props out there with a marker D for diamond, and these statistical outliers, so if there were no statistical outliers, these whiskers would go out to a minimum and maximum value, but if there are outliers, that would be values that are more than 1.5 times the interquartile range, the interquartile range remembers the difference between the value at the first and the third quartiles, multiply that by 1.5, add that to the first quartile, subtract it from the first quartile, and any values beyond that would be suspected statistical outliers, so that's how that would happen. I've put the mean line to true and show means to true, so you've got to do both of those to have that tiny little dashed line there which you can hardly see, so it's only when you have very skewed data that the mean and the median will not be close to each other, of course, and it'll make a bit more sense, the notch is true this time, and what we're doing is we're setting bootstrap equals 5000, so it's 5000 bootstrap re-samples, and we're using percentiles then of course to work out the up and down limits of that confidence interval, so title, label, label, x-ticks, remember the x-ticks, we had to do exactly the same thing, so there I'm just doing 1 and 2, becomes group 1 and group 2, that's how we did that, the pram, the tick prams, the grid, and then something a bit new, I'm saying plt.gca, get current axis, axis, axes, and there's only one axis on this figure, and when we get to the object-oriented interfacial, understand what that's all about, so I'm getting that axis, that's this whole plot on this figure, and I'm setting that to ax, and then I'm saying ax.set__frame__on to false, and you can see the frame that goes around, that's now gone, but you can only do that really in the object-oriented interface, or it's easier to do it with object-oriented interface, but to get to that I had to use plt.getCurrentAxis, and there's only one here, in a few minutes you'll understand what's happening there, and I'm just setting this frame to be off. Okay, enough of using the pi plot sort of interface, let's go to object-oriented interface, and that allows us a much more control over what kind of axes we can put on a blank canvas called the figure. There we go, the object-oriented interface, and that as I mentioned now gives us a lot more control, you can click there to read a little bit more about it, so let's just go back to a simple plot, that's plt.plot, I've got my x-vals, y-vals, just put the o there, so it's going to be a scatterplot, and we put a little bit of a title there, there's sine wave with a bit of a random noise added to that. Now we've seen before that I can do the same and use this plt.gca to get these axes, and I've assigned that to the computer variable named ax, ax, and the type of ax, if we use there, we can see it's a matplotlib.axes.underscoresubplots.axes is one thing that's on top of this whole big figure thing, and the way that we get to all of this, I'm just using ax again there, you'll see we can use, you can use anything there, depending on what makes sense, this would be typical fig.ax, because this plt.subplots, it has two things, this outer figure, the big thing, the blank canvas, and then ax are all the different plots that we put on this blank canvas, and I'm not specifying anything there, so that's just going to give us this one blank canvas, because we haven't specified anything to plot on this figure, and so there's this one axis on this blank figure canvas basically, and now ax, ax, a plot itself has nothing in it, so let's put something in there. So just a little bit of stuff we're going to put in at the moment, so I'm going fig.ax equals plt.subplots, and this time I'm passing two values there, 3,2, that says put three rows of axes and two columns of axes, so six plots all in all on this same figure, I'm making the fig size quite big, 16 by 9, and now, because I now have six plots in three rows and two columns of them, I've got to use indexing to identify each of them, and because I have rows and columns, that's a long two dimension, so it's a array with long two dimensions, now I've got to specify first the rows and then the columns, so I'm saying ax and then zero, so that'll be in the first row in the first column, so that'll be the top left one, I'm assigning that to the computer variable ax1, and then ax1 is now what plt.plot would have been before, and this time I'm just using a set underscore title, and you'll see when we use this object-oriented notation, lots of our functions that used to just be plt.title now become set underscore, so there's usually a set underscore between, so I'm just setting the title, and then I'm going for ax6, my last one, so that'll be in row two, column one, so remember zero index, so that'll actually be the third row, the second column, that'll be the bottom right one, and I'm just setting a title there, and then plt.title underscore layout, you'll want to use that many times, because what matplotlib will do, if you've got many axes on the same figure canvas, things might overlap a bit, and it just decides how to put a bit of padding in between things, so there's no overlap, and there's obviously a bunch of arguments that you can set there, so that's what it looks like, and that's what I said, we have three rows and two columns of plots, and each one of them is an axes, because each one of them is a Cartesian coordinate system here, two axes, so that whole thing is an axes, and there's six of them, and as you can see, I referenced 00 to put a, then to put a set title there on that one, and this bottom one here, put a title there, and that's as simple as that, it's just that we use the subplots function, now there's many ways to go about this, so this would be one way, we'll get to that, so subplots, plt.subplots, and we have fig,ax, so it generates two things, the blank canvas, and then all the plots that go on there, great stuff, let's have a look at this one, let's run the code and see what it is, it's a plot inside of a plot, because now things become really interesting, so this would be one other way to go about adding different axes, before we said fig,ax, and using the plt.subplots, this would be another way to go about it, so I'm showing you two things, another way to go about it, and how to plot a plot inside another plot, so anyway I'm generating this fig underscore one, this plt.figure, fig size 6 by 4, and then I'm saying fig underscore 1.addaxes, so instead of using the subplots that already gave me access to the axes, I'm just adding one by one to the fig now, and that allows me to specify on this blank canvas, how much of this blank canvas does it take up, because it takes this python list argument, and it goes left bottom width and height, so I'm saying start on this blank canvas 5% from the left, and 5% from the bottom, because it's 0 0 on the top left, and 1 1 in the bottom left, to 1 1 on the top right, so I'm saying starting 0.5% over on the left side, 0.5% up from the bottom, and then 0.95 0.95, that's the width and the height, so then I'm using 95% of the width, because that's what's sort of left over for me, and 95% of the height, and then I'm just plotting a title on there, so you can see where it goes, and now I'm adding another axes, so another add axis, I'm saying go 60% up from the bottom, go 60% up from over from from the left, and then 60 up from the bottom, and then use 30% of the width and 30% of the width of the of this figure, and I've just added another title there, so that you can see the two different axes here on the same figure canvas, so remember that's one way to go about it, just do a normal plt.figure, and then add individual axes, or use the subplots, specify how many they're going to be, and then just reference each of them, now we had to use two indices there for row and column, if I, for instance, if I had 3,1, that's three rows and just one column, I wouldn't have to use two indices, because that'll be an array of just and longer single dimension, we'll see that in a little bit, great stuff, let's do this one, and we've seen that actually before, that I now can use set underscore frame underscore on, and I put that to false, and this time I'm doing plt.subplots 1,1, that's just one, that would be the same as just having plt.plot, but now I have axes to more things now, one thing I might have access to is these spines, so yeah, we've removed all of them, so these, the frame is actually called spines, so I'm going to use the set underscore visible method here, so I'm saying fig,ax equals plt.subplots 1,1, so it's just the one, I'm saying ax, that's now this, you know, my plot on my blank canvas, spines the top one, set visible to false, and set right to false, and what that's going to do of course is just take away the right and the top one, and you might want to generate that kind of plot. Next one, I'm going to run these two lines of code, and that looks more like something, you know, that's getting towards a final product, so look at all these things happening here, let's get into how we generated it, first of all we've seen the two plots before, but now we're using the object oriented interface just to put both of them on there, and I've got all sorts of text that I'm putting in here, we can see this little one with a sigma underscore 1, sigma underscore 2, showing the standard deviation, the mean is sort of implied in the plot by the height of the histogram, we know where the histogram sort of is high there, because it's kind of caution I suppose, and then there we have the standard deviation of each of those, and our legend there looks slightly different, and here we've only got drids in one direction, all sorts of things, let's go about all of this, first of all this text that's over here, you know, it can be quite a bit to type in, so we've just done it separately there, so what is it, it's sigma underscore 1 equals, and then the standard deviations, and then in the second column sigma underscore 2 equals that standard deviation, so how do we go about it, well we're going to use this join, so this is text for new line, so I'm saying join the following two things, that thing there, that whole thing, oh now I can't get straight to there, that whole thing there, join that with a new line, so two lines basically, so the first bit here, now this first bit here, that is just going to be for us just a bit of, you know, setting up Python to print values inside of a string, so first of all it's a raw string, it contains a bit of latex, I'm saying sigma backslash sigma, that gives us a sigma symbol, underscore, that's the underscore 1, that gives us a subscript, and then equals, we're using this notation to get hold of what follows there, which is an actual calculation, puts it inside of there, and only gives us two decimal places, so dot 2f, and what it's supposed to put in this place of this dot 2f is indicated by this percent sign, and then we have the percent symbol, and what we want is the standard deviation, now what did I get drawn here, of course this is from a sample, so I should have put ddof equals 1 to give me a sample variance, a sample standard deviation, and anyway I have the second one there as well, and that's how we're going to get the text, and how are we going to go about this, a new way, so fig dot and instead of ax, and then I index the ax, I'm passing a tuple of axes, axes, so and I'm just going to call them ax1 and ax2, so as you can see down here, I refer to them individually, it's going to be a subplot, so plt dot subplots, 1,2, 1,2 columns, and that's what we see, a fig size, and frame on equals false, as far as the whole thing is concerned, so let's go to ax1 dot hist, it's a histogram for var group 1 and var group 2, we've seen that, we've seen also that we're setting the bin intervals, we're setting it as a step instead of full on, we're setting a label for our legend to use, and this time we're making the lines a bit thicker, we're setting two pixel line width there, so for both of them there, that gives us the ability to use legend because we set the label there, we're putting it on the upper right, making a font size of 8, making it a two column one so that we're next to each other, we're making the edge color gray, and we're making the face color light gray, if we're into that sort of thing I think it looks ugly, but there you go, show you that it's possible, we're setting a title, so instead of plt dot title it now becomes ax1 set underscore title, and a y label, and an x label, etc, and then the text, where do we position this text, well there's a way just to do 0 0 to 1 1, the whole thing, but what we do here if we just use what I can say, what I can call the default way, it's just to look at the axis values itself, so 60 on the x axis, there is the 60, and 200 on the y, it's up there, so it's going to put this box around about there, and you've got to sort of experiment with it, then put the text, remember which was this text that we had up there, and then bbox equals, and we're doing this python dictionary there, face color to white, and edge color to gray, so a little gray edge color and a white bounding box, so it's white on top of this grid, so you don't see the grid shining through, and we can just call grid there, and then the box plot we've seen before, so there's nothing new there, except for we set the frame to be off there, the frame to be off, and what else did we change, the x sticks labels, we've put them there, group one and group two, and you see we're not making use of any kind of overwrite there, so set x sticks labels, we can just put group one and group two right there, what else did we change, we have this right at the bottom, experiment one, so that's right at the bottom here, and that is on the canvas, not on the individual axis, so there'll be thick dot text, 0.5 is 50% across, we can also set that horizontal alignment to be centered, so the horizontal alignment of the text there to be centered, and by the way it's 5% below the bottom margin of the whole figure, and we've got the text itself there and the font size, and when we get to the grid here, before we just set ax1 dot grid, what we've got here is ax2 dot y axis dot grid, so you can set them separately, and only that one is set to true, so that we don't get the vertical grid printed for us as well. Now as I said here, we're using the 6200 and that pertains to the actual coordinates on our plot, what we can do here, let's run this, is setting it all up a little bit differently, and using grid spec, so let's have a look at grid spec, so fig is a plt.figure, I'm setting tight layout to true, doing that right as an argument, fig size 1629, and now I'm saying gs equals grid spec dot the grid spec function, uppercase g uppercase s, 2 comma 2, so I have two rows and two columns, but what we can see here is that the first row is taken up by one single plot, instead of having four plots in the 2 by 2 layout, so how do we go about that? ax1 is a fig dot add subplot, and then I say gs, 0 comma all, so ax1 is fig, remember this is how we do it, we can add a subplot separately before we add axes but add subplot, and we use the grid spec to say row 0 over all the columns, so that's going to give us over the whole thing and we can see the basic plot there, and then for ax2 it's going to be a fig dot add subplot and then the grid spec 1 comma 0, so row 1 column 0, so that'll be the second row, first column, and then over there we do the whole thing, and then over here the second one, and you can see I've done things slightly differently, the model is in there and then the interpolated line is there, what I was going to show what I didn't put in the plot is just this little text I caught my eye over here, remember here I just spoke about the 600-200, so let's get back to that, you can do the 00 to 11 across the whole thing by setting this transform equals ax and whatever ax you're dealing with at the moment, ax1 dot trans axes, lowcase t uppercase a, when you do that instead of doing the actual values as far as what is on your grid is concerned, your x and y axis coordinates, you can then put like 0.05 and 0.2 you know to go 5% from the left side and 20% up, so you do that just by this extra little argument that you have to set there, great stuff, so grid spec is something I think in the end if you generate reports you'll use most of the time, right, so the last section we're going to do some other type of scientific plots where we're just going to use some mathematical functions, so we're going to look at vector fields and gradients etc, and then lastly I'll just show you how to save plots, so plots for functions and vectors, first of all let's do a contour plot, you get two types of contour plots, one that's filled and one that's not filled, so you get contour f and this contour, so let's consider this function in two variables, this f of x and y is x squared plus y squared, nothing magical going on there, we're going to now generate a grid, so if you've never seen this numpy dot mesh grid before, the first time you see it, the first couple of times can be a bit slightly confusing, what it does is it creates a grid of x and y coordinate values, as simple as that, and what I'm doing here because my x and y coordinate looks exactly the same as far as the interval is concerned, I'm just you know cheating a little bit, just putting a single underscore there and numpy dot linspace negative one to one 200 values, so it's an array of 200 values on that interval negative one to one, and now I'm placing this on the mesh grid, it's the same set of 200 values in that array and the same array there, so that just gives me this grid, you know it starts at negative one, negative one, you know on the bottom left and goes to, well won't go to one, you know just under one on the top right, so it's just this grid of values a comma b x comma y, you know it just creates that grid, and because my x and y look exactly the same, you know I can just do this, otherwise I would have done x and y separately and passed x there and y there, and it's typical to assign that to uppercase x and uppercase y, and then my function is x squared plus y squared, so what that does is because I have this grid of values of x comma y values at each one of those little points on this 2d grid, for that little point it takes a value x squared comma y squared, so you can well imagine then you can plot that can be your z-axis and that's the height along the z-axis of any of those points, that's what mesh grid does, really not not that difficult, but let's create instead of creating 3d plots, you know which is kind of a hit or miss thing most of the time, it's rather create a contour plot, I think that makes a lot more sense, so let's do plt.contourif, that's a fold contour plot, x comma y, so that's still all my individual x values, my individual y values, and then f at each one of those values will do, will do an x squared and y squared, so remember that x and y comes from this grid being formed, so each one of those values will have this f value, levels is how many contours I'm going to have, and we can use a color map, and I'm using the inferno color map, there's many color maps you can use, I'm also adding a color bar so that it's sort of a legend that we can read off from by the color, we'll see the different contours, and then putting a label onto that color bar and then just putting a title, so taking too long let me show what this plot looks like, there we go, it's a contour plot and it's x squared plus y squared, so you know what that looks like, and then there at zero comma zero in the center, that's way down here, dark and then it goes as it goes out in all directions, lighter and lighter, you know, as the z axis value goes up, and that's a full contour plot, and there's 30 shades there because we set the levels to 30, if you put less of course you're going to have larger gaps in between, let's just do that, let's put 10, just to see what this all looks like, and now you can see there's only 10, now that's a full one, but we can only do the contours themselves, so let's have a look at the contours themselves, and so that looks very neat, so how did we do this, where we have the actual values on those contours, so first of all it's plt.contour not contour if, exactly the same stuff, x and y from our grid, if the value at each of those grid values, I only want 10 levels, and I'm using the plasma color map here, but I've got to assign that to some variable this time I've done c, so that I can say plt.c label, and the first argument is the whole contour plot, and then fun size equals eight, and what that's going to do is put these values, you know, one value on each of these little contours, and it works out sort of a way to put them, and then just a title, so very neat kind of plot there, so let's do quiver plots for vectors, so first of all I just want to show you how a vector is generated, I've got a position here zero zero, and a direction two one, save them as computer variables, and let's plot this thing, so what it does is quiver, so this time we're using fig.ax, plt.subplots, fig.size equals 3.3, tiny little plot, and then the quiver function ax, I remember it's my axes on my canvas, x plus y plus, so that's where it starts our little vector, and then the values in the x and y direction, so there was two across and one up, and you can sort of see the slope there, it's going to be a half, and then you can scale it, some scaling factor, and then I'm just showing the axis, the axis, what is the limits for the x axis, comma the y axis, so all that is passed is there as a single Python list, and then I'm using the set underscore aspect function to equal, so that we don't get distortion because it's rectangular and you're distorting one of the two axes, so that's, you know, to put one little vector on a vector field, and of course that would be hard work if you had to do all of them, so we can do better, so let's just look at a little vector function there, so in the two unit vector directions, i hat and j hat, I have x over five minus y over five, so you see two different notations there for how to write that vector, of course what we're going to do is create a mesh grid again, so because x and y is going to be exactly the same, I can just set one of them, so it's going to go from two to 2.2, and this time it's the a range function, so we're going up in steps of 0.2, we're setting that as a mesh grid, and because I want exactly the same values for both x and y, I don't have to do them separately, and then I have u and v, so how this works, you obviously don't have to use u and v, but as this common notation, Matt Blotlub uses it as well, so this is a vector valued function, of course, so x over five is my x and negative y over five is my second function, and we denote that separately for u and v, so u is x over five, and v is there minus y over five, and that denotes the direction basically, or really, so let's look at this plot, there we go, we can see it, and there's our vector field, and we've also got our little legend there to show our vector valued function, so how do we go about this? We're using the standard wave, a fig, a x equals plt.subplots, we're putting our fig size, we're using quiver there for our ax, ax.quiver, we're passing the mesh grid values there, and then these two, the directions, and the value for each of the x direction and the y direction, we're setting the limits of our axis there, we set the axis aspect to equal, and then we've given it a title, and now about this little text here at the bottom, so I'm putting it at zero zero, so we're not using the trans axis thing, it's here at zero zero using the grids specifically, and I'm using a bit of Lahtik there as you can see, and then instead of just saying font size equals 14, this is another way to go about things, a font dict, so you can use a dictionary, and there's lots of key value pairs, keys you can put inside of this font dictionary, I'm only using font size there to be 14, and bbox, I'm also using a dictionary there by setting the face color to white, and the edge color to gray, so that I can plot right over some vectors that might be there, and they don't shine through, because the box is now white. Great stuff, so there's our vector field f, and by the way with Lahtik you see my f there, and this time around it's got a little arrow over it to show that that is a vector, so instead of using math bb for blackboard, I'm using the vik Lahtik code there. So let's think about a multivariable function here, f of x and y is x squared minus y squared, we want to take the gradient of that, remember that's how we do that, and that's the Greek letter nabla, so you can see nabla there, so it is the partial derivative of f over x, and the partial derivative of f with respect to y, or you can also write it as f sub x, there's lots of notation for that, but you know what the gradient is. Now the first thing I sort of just want to show from SimPy, but because SimPy is one of my favorite packages, so let's make x and y mathematical symbols, so sum dot symbols and x and y, so now they're mathematical symbols, and I can set up this computer variable x to hold x squared minus y squared, and you can see they are now no longer computer variables, but mathematical symbols, so they'll print out nicely to the screen x squared minus y squared, and I can take the first derivative, partial derivative with respect to x, f dot diff, and I'm doing a first derivative, so only a single x with respect to x, and of course that function x squared minus y squared with partial derivative with respect to x is just 2x, and the partial derivative with respect to y is just 2y, minus 2y, it's x squared minus 2y, and now I can evaluate that at certain values by using subs, so I'm saying f dot diff x, so it's a partial derivative of f with respect to x, at 0.2 comma 2, so let's do 2 comma 2, so I can say dot subs x comma 2, so x is 2, dot subs y is 2, so what is that at 0.22, of course that's 4, and when we substitute the partial derivative with respect to y at this point, of course we get negative 4, so we know at this point sort of what that vector should look like, we've done that, so just a sort of sanity check when we actually do our plot that things are working out, so I'm going to do my mesh grid as well, going from negative 2 to 2, I'm setting up my two partial derivatives now, because remember what the partial derivatives was a slope at that point, so it's 2x, there it was there, we got the 2x there, and negative 2y there for the two partial derivatives, we're setting that up as unv, and now let's see what the plot looks like, there's our gradient plot, so I've got my plot there, and of course you can see the saddle point there for x squared minus y squared, and I've got this little mark at the top to show that the length of that vector is 10 units, so let's see how we put that up, fx, x plt.subplots, and I've got my quiver again as per normal, but this time I'm assigning that to a computer variable because I've got this function quiver key, and the first argument is the whole vector field there, and then I'm saying 0.85, 85% of the way across going from 0, 0 at the bottom, go to 0.85, then go to 2% above the plot, 1.02, and make it 10 units long, and because it's 10, I'm putting that as a text there, 10 units, and the label position is e, you get east, east, north, south, and west, so that is going to the east, to that side of the little arrow, so you can position where you put this text with respect to your little marker there, so that's how I would go about that, and that's our gradient plot there. Of course, we don't have to use some pi, we can just use numpy all the way, so I'm going to create this instead of f, a new one, because f now had the mathematical symbols in it, remember, so let's say my underscore f, and I'm using the mesh grid values there, x squared minus y squared, and we just call numpy dot gradient, and we want the gradient there to be my underscore f, we're taking the gradient of that function, and then the 0.1, we just have to be careful about that, because when we set up these values, let's just go back up there, where did we set them up? It was negative 2 to 2 over 20, so the gaps in between was 2 over 20, so it's a 10th, 0.1, and that's where we get that 0.1, so we set up that gradient, and now there's one thing that will always catch you out, the gradient does the derivative with respect to y first, and then the derivative with respect to x, very funny, but anyway, so switch those around, it's the first v, and then u, and then we can do that plot again and get exactly the same thing, so I showed you a bit of some pi, because that's always fun to use, but you can just stick to numpy, and you get exactly the same thing, and by the way we looked at 2.2, and you can see that's sort of up there, and it goes across 4 to the x direction and negative 4 on the y direction, so it kind of makes sense that our gradient field there worked out very well for us, and of course we can plot that over our contour plot and see if things make sense there, and of course it does work out pretty well for us, because remember the gradient always points uphill, and so the yellow remember that's up and the dark is down, so it's always pointing uphill, and we have the saddle point there in the center, and our vectors have got to be perpendicular at each point to the contours, and you can see every place they are perpendicular to that contour. Lastly I want to show you, well second, last I want to show you stream plots, and so let's just plot that out, first we'll see what it looks like, and then go through, so I'm using a 1.3 subplots there, 1.3 plots, and I've got a new thing there, share y equals 2, because you can see the y-axis is shared by all three of them, so I'm not printing these values negative 2, negative 1.5 on each of them, they share a y value, that sort of looks better, so we've got the three stream plots here, the first one you know it's the same vector field that we're looking at here, so it's stream plot x, y, u, and v, title basic stream plot, so you can sort of see the saddle point there and how things would flow if you put a marble on their position, what sort of what the flow is going to be like, remember the vectors go to maximum values though, so that'd be the opposite, but anyway the second one, and by the way I'm using axes there, just the different ones, but because I just have this along the single vector, 1, 0, 1, and 2, I just have to use, I said before, just the 1 index, so axes 0 will be this first one, axes 1, the second one, axes 2, the third one, and then the second one, I'm adding a magnitude by color, so of course as we go off here, it'll, you know, it'll, away from our saddle point, it'll get more and more, so the colors change, I put magma as my color map there, but I'm working out the magnitude and magnitude of that vector, of course, we're working in an R2 here, so that's just the square root of x squared plus y squared by the Pythagorean theorem there, so I'm sending that to MAGN for magnitude, because my color is going to be decided by the magnitude, so that's one way, and then instead of the color, you can also use sort of the thickness of these to indicate as far as the stream plot is concerned, and we do that by alternating the line width, and what we're doing here is magnitude divided by the maximum of the magnitude, simple as that, I'm just multiplying by 4 just to thicken them up a little bit, and then it's still the stream plot, and you get that nice plot there. Last thing, how to save a plot, remember we imported OS before, if you want to know where your notebook is saved at the moment, you can say os.get, current working directory, I've saved it to a variable path there in case I want to join this path to something I don't want to at the moment, the way to do that is to go for the fig, now that'll be the last one we used, so that would be this fig here, so these three here, and then there's a save figure, simple as that, and then we're just going to give it a name, and sort of this is a PNG, you can put JPEG, PDF, you can look on matplotlib for all the variety of different file types you can use, I've got an images sub folder inside of this folder where this notebook is, so I'll just put it out there, or this is a Mac, so that's what the folder structure would look like to the desktop, and the user name, and then desktop, and then put the plot there, so you can just decide where you want to put that plot, and that's it, I mean that's as much, you know, as much matplotlib as that I can squish into the short time, matplotlib is a beast, we have barely, barely, and all this time scratch the surface, but I think you've got a good start now, go out and use matplotlib.