 Okay, and we will go to another library. So the plots library, which is a kind of an instant interface for many packages used for plotting in Julia. So it's a very, very useful single package that does a lot of things. So we have already done in the installation instructions package.add plots. Then we just run using plots to get all of the functions. Mainly the function you will need is just called plot. So a bit of extra information here about different backends for this plotting library. This plotly is Julia, a bit more native. It still uses other backends. There's pyplot that will use mudplotlib. I'm not sure if gr is a Julia framework. It's like the kind of default back end of plots, like the simplest one. And actually the one that I use the most generally. It's pretty nice, I guess. Hardly ever need a pyplot or plotly. Unicode plots is, well yeah, you don't actually have to activate gr. It is activated by default. And then Unicode plots is for terminals. So yeah, you can plot in a terminal and it will look relatively nice. Yeah, our style plotting, there is catfly. Okay, so if you want to use pyplot, you need to add it. I'll just run that. But actually I will use gr, not pyplot. So yeah, you can run gr to activate the gr back end. But like I said, you don't have to. It's already there. This is a leftover from something I did before. Previous version of the nodes. Let's just continue from here. Okay, so this is actually a new thing. And the include keyword allows you to essentially do what it says in the box. It will take a file and plot it directly into your code. So this is just so that all of the functions we have written for the epidemic simulation don't take a huge amount of space in this notebook. So this file contains all the functions we have written so far. It also contains a make plants function, which is basically what we did in the previous one in a cell to create the plants, but it's in a function. So it really returns a matrix of plants. Let's run that. Okay, 32 times 32 matrix of plants takes a bit of space here. So it doesn't quite fit on the screen very well. To properly plot this though. At this point, I will move here and actually I'll just copy what we just did here. Okay. Interesting. Because I'm in a different folder. So it's actually just epidemic.jl. For me in this notebook. Okay, that's better. Right. So this is now no longer a great way of showing the matrix. Actually, we defined the print function or showing a single matrix. This might talk a bit better. I guess I didn't have it in the epidemic.jl. All right, fine. Because what we're going to do is make a much better visualization using the plot library. So I'm going to do using plots. And then, well, the first thing, so we could try the plots library contains the function plot. And you can throw in a lot of basic data types, for example, an array, and it will provide a nice plot for you. Now it has to compile the plot function. So it takes a moment. Right. But an array of plant type variables is not something the plots. Okay, here we have the graph. And that's not something that the plots library can just take in directly. Okay. So we need to define what needs to be done for the plants is not the thing that actually contains some data. It's actually plants with the capital P is not even defined. Okay. But yeah, it cannot convert it to series data for plotting. So, yeah, it doesn't really understand what's going on here. So we will convert this to colors to a 2d, essentially a matrix of colors, an image with some pixels. And to do that, we'll need to write a function that converts a single plant to a color. Call it two colors, plant. And the plant needs to be of type plant. Okay, that's what makes sense. Is the plant Oh, because you need two columns here to specify the type. Okay. So I guess I hope that makes sense at this point. So we're defining a new function that takes in a plant that is of the type plant. Okay. And what we'll do is basically just return a different color for each possible status. So we'll just start with plant status equals uninfected. Okay. Now the plot library also defines a function called RGB that returns a color. Actually, now that I think about it again, let's just demonstrate it first. So if you run it with the tape point, let's just do zero, zero point eight and zero. Okay. So that's green. We could just do zero, one, zero. It would be a light green zero point eight just looks kind of nicer for me. Of course, it's the first one is red. And then there is blue, right? So yeah, you can define colors this way. And we'll just return a color for each possible state for a plant. So we'll do zero, zero point eight, zero, four and an uninfected plant. Okay. Plant can also be infected. And I guess infected should be something like red. So let's do point eight in red. There are other states around. So a plant can be dead. And it makes sense for that to be basically black, but we'll make it kind of gray. So put some color in every, some value in every color, but the small one so that it's basically black. Recovered. Recovered plants are healthy, but we'll want to separate them from the uninfected ones. So we'll make them blue. And finally, teres immune. And immune plants just don't get the disease. So they're kind of like recovered, but not exactly. So what I've done is use a slightly lighter blue. Let's say point three here. Okay. So basically just actually we could use an else if here, right? So we just go through all the possible types and for each, so all the possible states and for each state, we return a color. Define that. Okay. Now we can pass a plant to that function. Let's make it uninfected. And it doesn't really, this colors function doesn't really care about this number. Infected will return a red color and so on. And now what do we do to pass the entire matrix to it? To, to turn the entire matrix of plants into a color, into the colors. Well, we'll just use the dots and tags like this. And we have a relatively nice looking image already. It's interesting that this takes less space than this. Oh, I had it in the different window. Okay. But this fits on the screen. But if it was a bigger matrix, it wouldn't fit on the screen. So what we'll do then is to turn that into a single plot. So a matrix of colors is something that the plot function does understand. So we can run two colors, four plants and make that the thing we passed the plot function, the plot function. And it looks like this. Now just to make it slightly nicer, we can remove the, there is no legend actually here. There is a border. So we can remove the border by passing colon none to it. We can also, if there was a legend, we could get rid of that by giving legend equals false. You can give it, of course, other values as well. And now we get this nice green field with a red plant in the middle. Now I'll run an update step here. Okay, right. Sorry, I need some numbers here. So five for the recovery rate, recovery time, 0.02 for the death rate and 0.1 for the spreading rate, the infection rate. Okay. So this is what our simulation now looks like. Okay, let's skip the random walk section. I mean, what I, well, okay, now let's just do a break first and then I'll tell you something to do. But this is essentially, it's just running the plot function for different types of data, which is fun. Then there is an animation. So we can walk through those. And then we have a couple of exercises where this one will actually create the plot we had in the beginning of the course yesterday on the first notebook. Okay, but first let's just take a break. Okay, we'll come back. So I think we'll go through the rest of these examples. I will not type through them or do too much explaining. These are mostly showing you that you can pass all kinds of data to the plot function and multiple dispatch plus some logic in the plot functions. The plot function itself will make sure that it's doing something appropriate to that data. So you don't need, Trudy doesn't need a separate plot 3D function to create a 3D plot, for example, like here. So we'll do a 3D random walk. So this is a very fast way, a very short way of implementing a random walk in three dimensions. Because the different directions are completely independent, we can just create a list of XYZ coordinates. Because I'm not writing this down, I'll just remove that and run it. And so now it's printing Z here. It's an element with a thousand, a vector with a thousand elements. And these are basically not exactly random numbers, but the cumulative sum of random numbers. So it's the result of a random walk. Y is the same and X is the same. That's just generated by the same function. Okay. So the point is, you can take three vectors and give them to plot. And it will assume that that what you want is a 3D plot of where those are the coordinates. So this is what it looks like. Now, of course, running a function called plot 3D instead of a function called plot is not that huge a deal. It's not a big deal, but it is somewhat convenient. And it sort of demonstrates how the multiple dispatch thing works. So the function generally just kind of gives you an idea of what to do, what it does, and then the parameters tell you much. I give you a lot more information in addition of what the function is going to do. Okay. Now, there is an exercise about animations. So we'll do a bit of that later as well. What we'll do here is first run a simulation of a Lorentz attractor. So you can check it on Wikipedia. If you want to know what is going on here, these are the parameters for the attractor. And it will essentially, it's a particle moving in a, let's say a gravitational field. And the point is it creates an interesting plot. So this defines a function that then returns an XYZ triplet. So you can return multiple values in this way from function. Now, I don't think you need the global keyword before the variables. That's all I think from Julia 1.4. You don't need to remove it. Yeah, you shouldn't need it. Okay. So first here, we construct a plot using path 3D now, like I just said that you don't need that. But yeah, in all cases, but here for constructing the plot, this is useful because it creates a series of plots. So you can also check this function in the plot library documentation if you're interested. The thing that I'm mainly pointing out here is this at GIF macro, which you basically put in front of a for loop to produce an animation. There is also an at anim, which we are in fact using in at animate, which we are in fact using here in the exercise. That's most the same thing. But for the when you do it with at animate, you can save that to a file later. So here, this is basically a for loop, but it needs to return or the last result needs to be a plot. And it constructs an animation by taking those plots to be the frames of the animation. So we take X, Y and Z coordinates from the Lorentz attractor. I guess you still don't need a global here. Yeah, you don't. And we push this into the plot that we created here. And this then should return. So we could put the result into an object here and then return it explicitly. But this will return a plot object that is a single frame. Now, the end keyword is for the for loop. But then for the GIF, we can do every 100, which means there will be a new frame every 100 iterations of the loop. So let's run this and see what happens. X is not defined. So it didn't work. Do we need a global keyword here? Yeah, now it works. It's weird. We shouldn't need it. Maybe it's because of this GIF. Does it differently? So it's not just a for loop. It is a function. So maybe that makes a difference. I mean, I've done stuff like that. I generally don't need it, but I don't know. Maybe there's a different setup here. Okay. Do you think it was removed at 1.4, 1.3 in the use of global for loops? They should be 1.6. Yeah, you have 1.6. I don't know. But let's just use it if it doesn't work without. But that's weird. Yeah, maybe we can try to figure it out at some point if we have time, although how it's going, we probably won't have extra time. Okay. Well, so yeah, it's plotting the path of the object around this attractor. Okay. So you can check the documentation for the plots libraries for more stuff. So since we skipped the reading files, you might want to look into that at some point, but now we'll skip exercise five and do exercise four and then exercise six. So you'll need to run this to get all the epidemic related functions. And the colors, two colors function is in fact already there. So you don't need to find that and run it. But then this is already this in a function to make it faster. If it's not in a function, it's already getting way too slow. It's not a very good function because it does refer to these external parameters, global variables. So okay, but yeah, this uses the animate macro to basically do what the gift thing did. So at the end here, we have a plot. And that will take it will take this what this plot produces, it will take that as a frame of the animation. Then the function returns the animation at the end. And we then use the gift function to save it into a file or the epidemic dot give. And this is now we give it frames per second. We could also use skip to make it faster. But in this case, it's nice to see every frame, even though it takes a bit more space in the file. Okay, anyway. So let's do exercise four and exercise six. So please use the green checkmark when you are done. When we are about 50% done, I will start going through the solution. Just what was the problem? It was the matplotlib version that was used. It was another one. Yeah, okay. Because changing back and back and in GR solve the problem and then everything was working. Okay, so for this one, we want to take both. First of all, we have an X that's a range from I understand the 10. And we want Y to be the square of that. So running just this doesn't work because you cannot take the square of a range of numbers. But with the dot, we just take the square of every number in the range. And then we could just pass Y, which would then assume that the X axis just goes from zero to 20. So it's better to pass X and Y to define the X axis. And this looks pretty much like it should. So we have four checkmarks now. We have more checkmarks earlier. Oh, so yeah, here are also done with the animation. Okay, now we have five. Five is still less than 50%. You think we should still start moving forward so that we have time, a bit of time to go into the next actually start the next section before the break? Oh, we have six now. All right, great. Okay, so again, what we have here is we're first using plots again. And here we are setting the size of the animation so that it should fit in an output cell in this window. Let's see if it does actually make it a bit smaller already, because this window is relatively small. Okay, now I just run the cell, maybe no, it didn't accept my command. Good. Okay. So and then we make some plans. Now it's a big array, 64 times 64. There is a function called count infections in this epidemic.jl. I'll run this one just to get all the functions again. So there's count infections and count deaths and those we will use to, we will use to make the craft that we had in the animation. So just to be sure, I mean, you can probably figure out what those do. They, this is not the right one. All right, because it is in the top folder here. So what those do is count the number of infected plants and count the number of dead plants in the simulation. I guess I have to make the windows smaller. Okay. So yeah, it just starts with zero goes through all the plants. And if the status is infected, it increases by one and then it returns the same for if the status is dead, then you increase the number of deaths by one and return. So from what we've seen by now, we could do this in one function and it would be slightly more efficient. We could just return infections and deaths using this common notation like this. And we also could do this in one follow by saying for plant in plants. Okay. So now the first thing we do in the actual animation to create an animation frame, we update the simulation and we again need some random numbers here for the parameters. So let's say five time steps for the infection 0.02 for the death rate and 0.1 for the infection rate. That's what we've had before. Okay. Now, okay, now you can see the whole cell. We'll get count the number of infections and number of deaths and count add them into the list. So in the arrays, so in, yeah, let's just do upend or push to add it to the end. Infections is the array. So that's the first first parameter and then the number which is from count infections. And we give it the plants matrix. Okay. And let's also do deaths. So that's also an array. So we can just push to add one number at the end and then count deaths, plants. Okay. Plants as a parameter. All right. And then we'll need to create a plot. So we have the two colors function. So to plot the simulation state itself, where we do what we did before, two colors dot. And then, yeah, we just pass plants to it. It just takes that one parameter. The parameters function is actually plant, right. And to make it somewhat prettier, we can say what was the keyword again. It's border equals none. Border equals none. That just makes it look nicer. Okay. And then to the second plot now is one of these line plots. We display two things. So but we don't necessarily need to set the X axis to anything specific. It just sells from zero and goes out from there. So it's, we just give it two. Actually, if we give it two vectors, it will assume that one of them is an axis. So let's just give it one array that contains two arrays. I think that will work. Maybe I should check the solution before doing this. Infections and deaths. Okay. Let's see what happens. This will take a while, but hopefully it will run. I probably should be doing this properly and checking the documentation with you rather than checking. Yeah, this is what I remember is correct. Okay. So you give it an array of two arrays and it assumes that there's just one common X axis. All right. So this was a boring simulation, but it is doing the right thing. Now, this is just Y1 and Y2 for the labels. So let's give it some labels. Infections and deaths. So the labels parameter works mostly as you would expect. So now, oh, I didn't quite do it right because it's label, not labels. So, but apparently labels also does something. So that is a bit confusing to me. Yeah, the label is one single label. Yeah. Oh, no. Infection. Oh, it needs to be a matrix. Yeah, now you're plotting a vector of vectors. I think if you have infections and deaths, you have a vector of vectors. So you don't need checks. This is a vector of vectors. So it's a matrix. So this also needs to be a matrix. Okay. That is not 100% clear to me still. But anyway, that's how it works. The array infections, that is not a matrix, that one. It's a vector of vectors. That's not a matrix. Yeah. Oh, yeah. Okay. But this is a matrix, this label. Yeah. Yeah. I think it joins those. That's it. This is producing kind of boring results. I think if I have eight here, this will match exactly what I had earlier, what I had in the first animation. Well, at least it's sort of catching on the infection is catching. Okay. Anyway, this is pretty much what we had. I think this will fit. So pretty much what we had in