 Hey folks, in recent episodes of Code Club, I've been doing some deep dives into creation of climate spirals. We started out by making some static versions, and then we moved into animated versions. We made two different versions. One was modeled after the versions made by Ed Hawkins at the University of Reading, and the second version was modeled after a version that was created by NASA, who is where we're getting our data from. So this has been fun, and we have done this using chord polar within ggplot2. Well, say you don't want to use chord polar for some reason, and you'd rather work in Cartesian coordinates. We'll actually see in some future episodes when we try to make some interactive climate spirals that those tools for interactivity, they don't give us a polar coordinate system, so we'll have to make our own, right? So how would you do that? So in a polar system, we think in terms of a circle, or at least that's the mental model that comes to me, where you can think of a circle and we have a radius to that circle, and then we have an angle or theta, sometimes it's expressed as phi. So we want to convert that circle into an x, y coordinate system, right? And so what you could think of is a point on that circle being represented as a line from that point on the outside of the circle to zero, zero in the middle. So if you then know the angle of that line relative to the x-axis, as well as the radius, you can then use trigonometry, sine and cosines to go ahead then and get the x and y coordinates of that point out on the circle. So that's exactly what we're going to do today. We're going to figure out the angle from the x-axis up to any point on our circle, again, that being the climate spiral, and then our radius will be the temperature difference. Along the way, we'll have some fun making some other spirals to kind of show you how this all works. So I'm going to start with a blank R script to demonstrate some things. We'll go ahead and do library, tidyverse. I'll start by making a tibble, and we'll then have a column in there called theta, and we'll then give that a vector of values. And so I'll do seek, zero to one, and let's do it in steps of, let's do 0.05. And so that's going to be a vector, like I said, from zero to one in steps of five hundredths, right? And so then we can multiply this by two pi to get the radians around a circle. So we could do two times pi times all of that. And so now we see that we've got that column for theta, right? And so then we can add a column radius. And let's make that one, right? And so now we have basically the polar coordinates, and we now need to convert that into Cartesian coordinates, right? And so if I were to go ahead and plot this using ggplotas, you know, what would we put on x, what would we put on y, right? That that gets a little bit challenging, right? So x, we might think of, well, let's put theta. And y, let's put radius. And then let's do a geom line. So of course, we get a straight line. And so what we've seen in the previous episodes is if we add to this chord, polar, we get a circle, right? And so that it basically converts these values into a circular format. But again, I want to make a circle without using chord polar. So I'm going to go ahead and remove that. So back up here, I'll go ahead and add a mutate function. And I'm going to make a new value for x, and a new value for y, right? And so we're going to create two columns, x and y, x, I will map to x, y, I'll map to y, right? And so the formula that we'll use will be radius times, and then we'll use, let's try sign of theta. And then y will be the radius times the cosine of theta. And we'll pipe that into ggplot. And so we can see a very jagged line plot. And so what's happening is that we're using geom line. And so geom line connects the dots between different points in the order of the x axis, right? If instead we looked at our table output, we would perhaps notice that again, if we're looking at x and y, that that as we increase our x values going down through our table, we are decreasing our y value from one down to basically zero, right? And so that's basically I think the top part of a circle starting from 12 o'clock down to three o'clock. And so again, what's happening is that we're not getting this in the order of the points, we're getting it in the order of the x axis. So instead of geom line, we'd want to do geom path that then gives us a pretty nice circle, right? And so you can see that it's I guess a 20 sided circle because we're using 0.05 steps, right? And so there's a little bit of jaggedness to this. And if you remember the version generated by Ed Hawkins, it also had some straight edges between the different months. So let's do something fun. Why don't we go ahead and increase this up to 10. And then my radius, let's go ahead and change the radius and see what we can do here. So for radius, I'll go ahead and then do seek zero to one. And I want my length out to be the same as the length of theta. And so again, this should give us a table that's got theta and the radius. And as you'll notice, as we increase theta, we also increase the radius. So what do you think we're going to get as output from this? Yeah, we get a spiral, right? Isn't that pretty cool? And so again, as you kind of go around the circle, it gets bigger and bigger, right? Cool. Now we want to apply this to our code for making the climate spiral. Over here in files, I've already made a file called climatespiraltrig.r, which is a copy of climatespiralnasa.r. If you want this, you can go down below in the description for this video. There's a link to a blog post that'll get you everything you need to get caught up to exactly where I am, you'll get the code and the data and just just everything you need. Great. So again, this created the animated plot climate chart that was stylized after the NASA version. I'm going to go ahead and clean this up a bit. And maybe what I'll do is I'll go ahead and remove that geome rect, as well as the scale X continuous. And yeah, let's just clean out anything that's commented in here. And yeah, so I'm going to then save this as climate spiraltrig.png. And I'll leave that in. And I'm going to also turn off this transition stuff that was in here from Gigi animate. I'll probably bring that back in later. Before I forget, I'll train this NASA into trig as well, as well as this one down here for the MP4. But for now, for developing this out, I'm going to go ahead and comment all that out. So we don't have to worry about that. And also I have this assigned as a variable, a, and so I'll comment that out as well. And so what I've found is that when we're making these animations, it takes a long time to render the animations, it could take like half an hour. And so if I'm testing things out, I don't want to have to worry about the animation. All right, so let's go ahead and run this and see what things look like now. Great. So that looks exactly like we'd expect it to. Let's now go in and turn off the cord polar. So I'll go ahead and comment that out. And so now we can see what this looks like without things being in polar coordinates. Great. So let's go back through our code and recall what we have. So T diff then is a data frame that's got the year, the month, and the temperature difference relative to the temperatures, the global temperatures between 1951 and 1980 with for this particular data set. Okay, we then had this other data frame next Jan, which helped us to get a jump from December to January. And so if you think about these weather lines that we have here, again, they're drawn as lines. It's not a continuous line, right? And so basically it needs a way to get from the right side of the screen back to the left side of the screen to start things over again. I'm going to do it differently this time because I'm not going to be using cord polar. I want to make one long line like I saw showed you in that big spiral, let me make one long line and then show us how we can spiral it over itself. And so what we will do is go ahead and comment that out for now. And I'll think I'll go ahead and remove this bind rows for T diff and next Jan, right? And so now what we've got is T data, which gives us the month, the month number, and then sorts it and removes the year 1879. So again, if we kind of run each of these lines in turn, we start out with the month number. So this is one through 12 for each of the months. Again, if we looked at the tail of this, we would also see it ending in three because the data goes to March of 2022. We then sort it just in case our years and months are a little bit out of whack. So then we have this filter year not equal to 1879. That's again, because we had the next January added. So if we look at the top of this, we know that we don't have an 1879. So I can go ahead and remove that and then there's a line in here for step number. And so this basically is going to number each line of our data frame. And I'm going to go ahead and leave this in. Because again, if I look at T data, I can then have my step number going all the way out to the end of the data frame. So if I then do tail on that, it goes out to 1707. And so what that will allow us to do is basically plot our T diff as a function of step number. And then we can also animate by each month. So one of the problems that we've had in the previous animations, so we have to animate by year rather than by month. And so step number will make it easier for us to step by each month, I think. So the next thing I need to do is to convert either the month number or the step number into a theta value, and then use T diff as the radius so that we can create our own polar coordinate system. I'm going to do that back here where we're creating T data. And so we'll use radius. And that is going to be T diff. And then we're going to have theta, which is going to be, let's go ahead and use month number. So again, that now gives me my radius and my theta. The theta though is the month number. So one for January and 12 for December, I need to convert that into an angle in radians. And so to do that, I'm going to go ahead and subtract one from the month number so that January starts at zero, December at 11. I'll go ahead and put that in parentheses. And I'm going to then want to divide that by 12. Looking at T data, then I see that my theta goes from zero, probably down to one. And so I'm pretty happy with that. But I need to convert it to radians. So I multiply that theta by two pi. So two times pi times all that. Looking at T data, let's see more of that first year, I'm going to go ahead then and slice head. And I'll do n equals 12. And T data, we then see we've got a full year's worth of data, right? And so then we go from zero to 5.76, which I suspect is 11 divided by 12 times two times pi is 5.76. So that should be good. Now we want to get our x and y positions for these this radius and the theta. So it's going to be radius times, and it's going to be the cosine, because it's adjacent divided by the hypotenuse, right? So cosine of theta, and then our y will be the radius times the sine of theta. So let's come down to the plotting code. And we're going to want to update our x to go to x, our y to y, we don't want a group variable. So I'll remove that. I'm also going to remove this GM label. That was the year that goes in the middle of the plot. And then let's go ahead and run GM label or GM line rather with the GG plot and our data. And what we see again, we saw this before, is that it's going from left to right along the x coordinates. And so we need to convert GM line to GM path, like we saw with the spiral and circle that we made a little bit ago. And so, yeah, so now it starts, I think, yeah, so why we saw it was here. So this was January, February, March, April, May, June, we could double check that by doing GM label. And we could do AES label month. And so yeah, we see if it goes January, February, March, April, May, June, goes counterclockwise. So let's go ahead and try to switch the sine and the cosine. So do sine and cosine. So that then gives us January down low, February, March, April, May, again going clockwise, but from bottom up and around. So I think what's happening is that if we look at t data, that the radius again is the amount of temperature difference. And I we need this to be positive, right, because right now our radius is negative, rather than positive. So what I'd like to do is let's add a factor to the radius so that we're sure that our radius is always greater than zero. So it doesn't make sense to have a negative radius, because that's going to put us in the opposite direction. So we'll come back up to our t data data frame here, right? And so I'm going to add to this, let's do 1.5. We never had temperatures get below negative 1.5. So we'll do that. And let's see what it looks like now. That looks better, right? Now we have January at the top going all the way around. And I'm pretty thrilled with that. All right. So I'm going to go ahead and remove the month labels. And let's also go ahead and add another year's worth of data. So instead of slice head, I guess we could do n equals 24. We now get two loops of the climate spiral. And we don't need that next jam data frame like we had before. Because again, we're doing a genome path in these Cartesian coordinates. Great. So I could also then come back up here and remove that slice head. So we've got all of the year's data. So there is our climate spiral, just like we've had before. One subtle difference, however, is that you'll notice again that the connections between the different months is a straight line rather than curved. When we use cord polar, it naturally curves that line for us. If you wanted to, you could interpolate between the months to get more time points there, right? And so then it could look a bit more curved. But I'm going to be happy with this. I'll let you play around with that if that's something you're interested in doing. Okay, now we need to build out the rest of the plot. So I'm going to go ahead and make sure I've got all of these other data frames loaded that we use to make the pot look pretty. And that and then I'll go ahead and bring back in the label. Again, this should be the year in the middle of the pot. So now we see that our label is centered where we had it before rather than at 00. So we see, of course, that our year is at one negative 1.7, rather than 00. So let's go ahead and turn that to 00. Good. So now we have our year in the middle, just where he wanted it. So now we'll come back to the next line, which is GM segment, which is reading in from grid lines. And so grid lines is a pretty simple tibble. As we can see, it's got three lines that we're generating for x, xn, y, yn. And so this would this goes into GM segment, but it's not in our polar coordinates, it's in Cartesian coordinates, right? So if we ran that, what would it look like? Right. So it draws them in Cartesian rather than polar, obviously, because we didn't tell it to turn it into polar coordinates. So we saw how to make grid lines like this before, when I was doing a brief demo of how to make a circle, right? So let's do that again. And so what we'll do is come up in here and we'll do tibble, and then I'll do theta equals two times pi times seek from zero to one. And let's do in steps of point 01. And then our radius, let's let's do one, that will give us a one degree radius. And then I'll say line equals one degree. And so again, we now have that data frame. So I'm going to modify this, and we'll do rep on this. This again is the theta. And I'm going to do each equals three. And so that should repeat each value in theta three times. And let's double check that. Yeah, so that's good. So then on the radius, we could do rep. And we could do C, one, zero, negative one. And then I think we could then do length dot out equals length on theta, theta. And so now we see we've got one zero negative one. Good. For our line, then we'll come back and I'm going to copy this code. And then I'm going to give them arbitrary names of A, B, and C. And so yeah, so now we have theta radius line, we're good. And I will call this grid lines. Right. And I'll go ahead and comment this out for now. Load grid lines. So now I'm reminded that I need to convert the theta and the radius into x and y. So again, we could do x equals radius times the cosine of theta and y to be the radius times the sine of theta. And again, if we look at our grid lines, we now see we've got our x and y positions. So again, I'm reminded that we've got negative radius, right? So we need to add back in our scaling factor, which up here I had as 1.5. So I'm going to add a variable called radius bump. And let's make that 1.5. And then I can use radius bump wherever I want to add that factor, because again, we might come back and change it to like one or 1.1. And I don't want to update that 1.5 everywhere. And so down here in grid lines, we'll go ahead and add to this our radius bump. Right. And so now if we look at grid lines, we see that our radii are all positive. And so now if we come down to geompath with grid lines, x, x, y, y, and we're going to add a group. So we'll do group equals line. And I don't want quotes around line because that does different things, right? So it's giving me an error that it doesn't like how I'm doing my colors. And I think that's because I've got three colors, but I've got a whole bunch, 303 different rows. I don't want to set the color manually, because I need the color for the gradient on the color of the actual data, not the grid lines. So I think what I'll do is I'll break this geompath up into two steps. And so we'll have grid lines. So I'll do a filter radius, not equal to radius bump, right? And so that will basically be the zero. So you'll notice I'm using a filter within all this. Isn't that crazy? And I think I've got an extra parenthesis there. All right, so that's my AES. Let's just double check everything looks good. And so for my outer ones, I want those to be yellow. So I'll do that. And then I've got that. So okay, so let's run this and make sure we get our two, our one and negative one degree lines that worked well, right? So now we have our yellow lines. We need to add our green line for zero degree, where it was radius was equal to radius bump. So again, I'm going to copy this down. And I'll say double equals radius bump, make this green. Again, the reason we're doing this is because I need a different color scheme for those grid lines than I have for the actual lines. I'll trust that that works. We now want to add the labels to these lines. And so again, we're going to have templates. So let's go back up to the top and double check their location. So again, we had templates here, these are the labels on those templates. And so x needs to be zero. And then y is going to be these values plus the radius bump on templates. So let's add that and see if that works again, I'm modifying the code. And instead of running the whole thing through and getting all sorts of craziness, I'm running each step in a dip, adding on to the previous step, right? Very good. So those labels are now on the lines that they're supposed to be at 12 o'clock, so to speak. The next thing we need to do is add the month labels around the perimeter, which is this next geome text, which is getting the x and y positions from our month labels data frame, that again was way back up here. And so again, we have x and y in Cartesian coordinates, and they need to be in Cartesian coordinates, but they first need to go through polar coordinates, right? So for x, again, that's our theta. And this is basically like what we had way back up here for our month number for calculating theta, right? And so here what we'll do is look at and put that in parentheses, I'm going to subtract one from that, and then divide it by 12. And then we'll multiply this by two times pi. This will be our theta. And then the 1.5 will be our radius plus our radius bump, right? Now we need to convert our theta and our radius to x and y positions. So we'll do x equals radius times a sine of theta. And then our y radius times cosine of theta. And we can now run all this code all the way through that second geome text. Very good. Got it right on the first try. Good. So now we can move down to some of the more styling aspects where I don't think we have to worry so much about things being in polar coordinates or not. The first thing we have here is our scale y continuous with our limits. And again, the outer limit was negative two, and the inner limit was 1.5. And so what I'm going to do is I'm going to make this, let's do negative 2.5 to 2.5. I think we need that expand, but I'm not totally sure. So I'll leave it there for now. But I'm going to copy this down and make the same thing for our x continuous. I'm also going to add then chord fixed. And what chord fixed will do is it'll make sure that we have a circle and not an ellipse, right? So basically it'll make the proportions of our x and y fixed. And again, we're getting the warning message that we removed, the month labels, we're really zoomed in close. So I'll go ahead and make these limits plus or minus 3.5. If that's too much, we'll adjust. If it's not enough, we'll adjust again. So I think we actually want to go out a little bit more. So let's do plus or minus four on these limits. And that should probably be good sufficient. So that's good. I think this expand may have been screwing things up. I'm going to leave it since I got limits that worked pretty well. But I suspect if you remove that expand, then that three and a half probably would have worked fine. But we'll leave it. All right. So now we want to add in our color scale or scale color gradient to so that we get our line to be the right color. That all looks pretty good. So I think we can run the rest of the pipeline with the labels getting set to null all the way across and all of our theming. Very good. So we can then of course, send this off to our PNG file, I'm going to make the file square. So it'll be four and a half by four and a half. Nice. One subtle thing I notice is that our labels on these lines are on the lines. Whereas previously we use geome segment to have it go right up to those numbers. So I'm going to go ahead in and adjust those lines that we use for the grid lines. So I'll use a filter function to remove those rows from the grid lines data frame that I don't want to be included in the actual plot. So we'll get go ahead and pipe this to filter, and I'll do something like line equals equals a. And then I'll do theta greater than say 0.03 times two times pi and theta less than 0.97 times two times pi. So I'll wrap this in parentheses. And I will copy it. And I will then add an or to that. And I'll do another or right. And so these are going to be and C. And I'm replicating this three times, because we're probably going to need different parameterization for our Thetas. And I think I switched my sine and cosine over here in grid line. So I'll switch that real quick. So sine and cosine. But I can also kind of tell that there may be a little bit too big for some of these. So maybe for a line a, which is the outer line, maybe you'll make that to one and 0.99. So that looks better. And then back up here, again, I think I adjusted these a little bit in the last episode, I could probably look back at what I did in the last episode and adjust accordingly. But let's go ahead and make the B line. So 0.025 and 0.090.975. And, and then here, let's open this up a little bit. So we'll do 0.035, 0.965. So it looks pretty good. Maybe that inner circle could be opened up a bit more. I'm going to open it up a little bit more and make it say 0.05 and 0.95. Great. So I'm pretty happy with how that looks. Now what I want to do is be able to animate this. So again, coming back to our code, I will reassign this back to our variable a, right? So we have that there, and I can bring this up a line just to make it all work. Look back through this code, we can go ahead and remove our cord polar. Some of you are probably wondering at this point, Pat, it's a lot of work to not get very far. And so I'm now going to bring back in our transition. And I will do transition reveal on step number. And then we can then bring in our animate and animate save. I did make that trig, and I'll make the height and the width the same. So 4.5 by 4.5. So we have our animation running. I'm pretty happy with how this came out. Again, the subtle difference between this version and what we did in the last episode was that the edges on our climate spiral are straight, rather than curved. Again, that's because of the transformation that you get with cord polar on all of the lines that we don't have here. And so if we wanted to get more curved lines, you could go ahead and interpolate between the different months to get a more rounded appearance to the figure. Again, you might be saying, Pat, this was a lot of work to not get very far and perhaps even to have a figure that looks worse. Well, in the next episode, what I want to be able to do is to make an interactive visual, right? And so we could imagine that we have this X and Y or polar coordinates. But then you could also imagine this being a stack, right? So where each year is a different layer in the figure. And so that could be a three dimensional figure. And so if we want to use interactive tools to build out those figures, unfortunately, it doesn't seem that we can use polar coordinates directly. And so that's why we have to go through this initial step of converting into Cartesian coordinates, what should be in polar coordinates. So again, I hope you found this interesting. If nothing else, you learned how I troubleshoot through different problems. And you'll see that, you know, trigonometry functions do have a use outside of high school trig classes. I hope you had fun with this. And if nothing else, I hope it was a little bit entertaining. Please tell your friends what we're doing here on Code Club. And we'll see you next time when we start talking more about interactivity.