All right. 1
So in this lesson we're gonna be covering some advanced data visualization techniques. 2
And I'm going to show you how to create 3-D charts in Python. 3
So let's start off with a section heading, 4
change this to Markdown. 5
And I'm going to use the pound symbol, and then write "Example 4 - Data Viz with 3D Charts" and in the 6
same markdown cell, 7
we're only playing with a little bit more of the LaTeX notation. 8
Let me show you the function that we're going to minimize. 9
This function will have two variables. 10
So it's both going to have an x and y, and we'll have to minimize our cost across both of these inputs. 11
So both of these parameters will have to be optimized in order to minimize the cost. 12
So here's what our cost function will look like. 13
So I'm going to add a subheading and I'll say "Minimize $$f(x,y) =" and 14
then I'm going to use the backslash to put in a keyword here - frac for fraction and then 15
I'm going to use a curly brace of 1, close the curly brace and then have another opening curly brace 16
and then put a 2, and another closing curly brace. And then I'm going to put two dollar signs at the end 17
for my closing tag. And now let me press Shift+Enter to show you what this LaTeX notation actually looks like. 18
So what you see here is that we've created a fraction by using this tag right here. The top part of the 19
fraction is between the first set of curly braces and the bottom part of the fraction is in the second 20
pair of curly braces. 21
The function that we're actually gonna be minimizing isn't 1/2 it is 3 to the power of 22
and then it'll be another opening curly brace -x^2-y^2, 23
closing curly brace and then I'll add 1 at the end. 24
Now let me hit Shift+Enter to show you what this function looks like. 25
Voila. 26
Now a nice little trick with complicated functions like this is that we can split it up a little bit. 27
This also makes it easier to write it in the Python code so we can also write it like this, we can say "Minimise 28
$$ f(x,y) = "and then have again the "\frac{1}"and 29
then "{r+1}$$", and then "where 30
$r$ and $3^ 31
{-x^2 - y^2}$" 32
And what this line of markdown will nicely do is show us again the difference between using two dollar 33
signs in the LaTeX markdown or one dollar sign in a LaTeX markdown. 34
So with the double dollar sign we get that equation centered and with a single dollar sign we get that 35
notation in line. 36
Now let's write the Python code to express this function. 37
So I'm going to go with the second way of expressing this equation because I think it makes it much 38
more clear and easy. 39
So I'm going to say "def f(x,y):", "r=3**(-x** 40
2-y**2)". 41
And then I'll say "return 1 / (r+1)". 42
And I'll hit Shift+Enter. 43
And this is what our function looks like in Python. 44
So even though we could have written all of this in one line here after the return keyword I find it 45
much more readable if we split it up like this. 46
Now let's create a chart with this function. 47
Let's see what this actually looks like on a graph. Now as always with charts we've got to make some data 48
first so we're going to use that linspace function again, but this time we're gonna create data for 49
both our x's and our y. 50
So I'm going to create a variable called x_4 is equal to np for numpy, "linspace 51
(start=-2, stop=2)", and then num=200 and I'll do the 52
same for our y because we've got two variables now, so we'll have "y_4 = np. 53
linspace(start=-2, stop=2, num=200)". 54
So, while we're at it let's take a look at what the type of x_4 actually is, what type of 55
object is this. 56
We can see that linspace gives us a numpy array, an ndarray and we can also see the same thing 57
if I move my cursor over linspace, hit Shift+Tab and then I can see here if I press the plus sign 58
and I scroll down, it returns a ndarray. Yeah the linspace function returns an ndarray. So 59
I can see this both if I print out the type or if I take a look at the documentation. 60
Now the interesting thing with arrays is that they have a shape - they have rows and they have columns. 61
So what we can do is we can look at the shape of this array, we can say "'Shape of X array', x_ 62
4.shape'. Yeah, so shape is an attribute of the ndarray. So let's print this out, see what we get. 63
So we can see that we've got a one dimensional array with 200 rows. 64
A mathematician would refer to this type of data structure as a vector. 65
Let's keep that in mind for later and move on to trying to plot stuff. But before we dive into plotting 66
things right away, let's have a quick think about what a plot might consist of. 67
If we look at our previous Python code that say generated this plot right here what we see is that our 68
chart is in fact made up of different pieces that come together for the final product. 69
So for example we had our data points that were plotted as a scatter plot on the diagram and this was 70
separate from the line that was being charted. 71
Also our plot had other bits of information too, right? It had things like title and labels and so on. 72
The point I'm trying to make is that we've actually used several different types of Python objects to 73
make our final chart. In this lesson we're gonna be generating a 3D plot that will look something like 74
this. 75
However, to make this 3D plot we have to start manipulating other types of Python components that make 76
up this diagram. 77
These Python components include the figure object and the axes object. 78
Now we've already met the figure. 79
Remember how we sized our plots previously? 80
We did that by manipulating the figure size. 81
So let's come down here, I'm going add a little comment "Generating 3D plot" and let's size our new plot with 82
"plt.figure(figsize =)", and then we'll pass in a list with the [16, 83
12]. 84
So this is how we sized our figure always. 85
Now here's something new that we can do with this code. 86
If I hit Shift+Tab on this function then I can see by expanding the documentation and scrolling down 87
that this function in fact returns something. 88
This figure function has an output and it returns, well it returns a figure. Yeah a figure 89
instance will be returned. 90
And since this bit of code has an output, we can actually store that output somewhere. 91
So I'm going to create an object, call it fig and set it equal to the output from this bit of code here. 92
So now our figure object is stored in a variable called fig. 93
At this point you might be asking what's a figure? 94
And the answer is, it's a little bit abstract, conceptually a figure is just a matplotlib object that 95
allows us to manipulate our final chart in certain ways, like by say changing the size or adding axes 96
to the chart. 97
In fact you can think of a figure as a kind of top level container that contains other elements in the 98
chart. 99
That's just how the matplotlib library is structured. In their code that we're using 100
the figure is a container for other bits of the chart. Now, the follow up question is what kind of other 101
elements are contained in a figure? 102
Well one element actually is the chart's axes and we are particularly interested in the chart's axes because 103
we're gonna have to manipulate them. 104
So the axes we're going to store in a variable as well. 105
So going to say "ax = fig.gca(projection='3d')". 106
So what's happening here is that we're calling a function called gca which is short for "get current 107
axes". 108
So we're getting the axes from the figure and we're storing them in a variable as well. 109
So our fig object came in handy here on this line, because we're using the fig object to grab our axes. 110
Now I can't actually run the code like this, if I press Shift+Enter, I'm going to get an error 111
and the error reads "ValueError: Unknown projection '3d'". 112
The reason we're getting this error is because we have to import our 3D axes into our Python notebook 113
so I'm going to scroll back up all the way where we had notebook imports and packages 114
and here I'm going to add the code "from mpl_toolkits.mplot3d.axes3d import 115
Axes3D". 116
So it's quite a mouthful. 117
We're importing something very specific. 118
So "from mpl_toolkits.mplot3d.axes3d import Axes3d". 119
And then I'm going to have to hit Shift+Enter on this import. That way we've refreshed our Python notebook. 120
And if I scroll all the way down to the bottom I can now go to the cell and actually run it. 121
It will recognise our 3D axes and will actually generate an empty chart for us like this. 122
Okay, 123
I'm going to click back into the cell and add our next line of code because now that we've got our 3D axes 124
we can try plotting our function on them. 125
The method that we're going to call on our axes object, 126
so writing "ax." is called "plot_surface" so we're not plotting a line, we're plotting a surface because 127
now we're in 3D space. So we'll say "plot_surface()" and then we have to feed our data to it. 128
So we're going to say x_4, and then y_4 and then for our z axis, our third dimension 129
it's gonna be f(x_4, y_4) and then two parentheses at the end. 130
So this is the function that we want to call to actually plot a 3D chart and we're doing this on the 131
3D axes object itself. But before I run this, there's still something I have to do. 132
So let me quickly pull up the documentation here by pressing Shift and then Tab on my keyboard and hitting 133
the little plus sign here, we can see in the signature there are three required inputs - an x, a y, and a z, but scrolling 134
down we can also read that these three inputs need to be 2d arrays. 135
So they need to have two dimensions. 136
But let me ask you this - is x_4 and y_4 a 2D array as it is right now? 137
The answer is no. 138
If we look here, our shape that we've printed out is in fact showing us that we have a one dimensional 139
array. 140
So it's got two rows but it's only got one dimension. 141
So there's something we have to do, we have to make this two dimensional. Let me add some more lines on 142
the top here. To meet our requirement for our plot surface function, 143
we have to transform our x_4 and our y_4 to a two dimensional array. 144
So I've got a one dimensional vector and it should become a two dimensional matrix. 145
And this is where our good friend numpy comes to the rescue 146
once again. We've got a really, really good numpy function called meshgrid that we're gonna make use 147
of to do just that. 148
So I'm going to type "x_4, y_4 =", 149
you'll notice I'm using sequence unpacking here. 150
So "x_4, y_4 = 151
np.meshgrid(x_4, y_4)" 152
So what does mesh grid do? 153
If I look at the docs, I can see that this method returns a coordinate matrix from a coordinate vector 154
so it will return to us a two dimensional array given a one dimensional array. Let's print out the shape 155
so I can prove this to you. I'll say "'Array after meshgrid', x_4.shape", let's 156
run this again. And here we see that our array now is 200 rows by 200 columns. 157
So I can show you what this would look like actually but I'm not going to show you a 200 by 200 matrix 158
I'll just show you a five by five. 159
So I'm going to change the arguments here to our linspace function and then down here I'll say x_4 160
and we can actually see what it looks like if it was a five by five matrix. 161
So this still is two dimensional in contrast to what it was before we called the meshgrid function. 162
This print statement is showing us that here at this point it was still one dimensional but by the time 163
we've run meshgrid it has become two dimensional. 164
All right. 165
So I'll delete this really quick here and I'll change our arguments back to 200 and I'll rerun 166
the cell. 167
Now it's time to look at our 3D chart. 168
So let me add plt.show() and hit Shift+Enter. Scrolling down we see our beautiful 169
surface being plotted on a 3D axis just like this. 170
Very nice. 171
So I'm very proud of our creation here. 172
But the I think it could use some improvements. 173
For starters I can't really tell which axes is which 174
just by looking at this. 175
So what we're gonna do is we're gonna add some labels to our axes. 176
Now here's the thing. 177
Previously we've added plt.xlabel, 178
yeah and had a function call like this but we've got a 3D chart and so we're going to call our method 179
on our axes object. 180
So we gonna say "ax.set_xlabel()", and then we'll pass in the string X with a font size 181
equal to 20 and I'm gonna copy this code, paste it two more times, but instead of the X label I'll have 182
the Y label and the Z label as well. 183
And of course I'm going to change the string to display to 'Y' and then I'll change the z axes to 184
'f(x, y) - Cost' so that way we'll have a label on all our three axes of our 3D chart. 185
Let me hit Shift+Enter and update what's on screen. Voila. 186
So this is what the Z label looks like. 187
We've got our X label and our y label. Brilliant. 188
So that's starting to look pretty decent. 189
But you know what, we can make it look even better. 190
And the way we're gonna do this is by using color, adding color provides so much additional information 191
when it comes to data visualization. 192
So my objective looking at this is to be able to visually differentiatem not just based on where things 193
are, 194
if a value is high or low, but what color a certain area is on this chart. I want the color itself to 195
tell me if the cost is high or low. 196
And to do that we're gonna have to import a module called the color map. So I'm going to scroll back up and 197
in our very first cell, I'm going to keep all the import statements nice and tidy up top, 198
I'm going to say "from matplotlib import cm", and cm stands for color map. I'm going to Shift+Enter 199
and I'm going to scroll back down 200
and then I'm going to modify this call to our plot surface function. 201
This plot surface function can take some additional arguments and one of these arguments is surprise, 202
surprise, 203
a color map. 204
So I'm going to say cmap 205
is equal to, 206
and then I'm going to use the color map module that we've just imported. 207
So I'm going to say "cmap = cm. 208
coolwarm". Cool warm is one of the color maps that we can use from the color map module. 209
So let me update this chart right now by hitting Shift+Enter. 210
There we go. 211
Isn't that amazing? 212
I think this is so, so cool but just like with our regular line plots and our surface plots we can actually 213
add transparency to this plot as well. So we can go back to our plot surface call and add a comma at 214
the end and then provide an additional argument, namely alpha equals and then say 0.4 to 215
add some transparency. 216
So let me hit Shift+Enter, update the chart. Now it looks like this with the alpha value at 217
0.4 218
we can even see our grid shining through on the back of our chart. 219
Now personally I think this chart is starting to look quite wonderful because we've got our high cost in 220
red and we've got our low cost in dark blue hues. 221
So we can already visually differentiate between costs that are high and low 222
just by looking at the color and also based on similar colors we can see which parts of our chart actually 223
have a similar cost as well. 224
I'm going to end this lecture on a challenge. 225
Can you change the color mapping of this chart? I mentioned earlier that there's quite a few different 226
color maps available and we've used one of them called coolwarm. 227
Can you dig into the documentation and change the color map on this chart to something else? 228
I'll give you a few seconds to pause the video before I show you how. 229
And here's the solution. 230
Part of becoming a proficient programmer 231
is getting really good at googling and I'll show you two pages that you can use to give you some inspiration. 232
So there's this one here where it's all about choosing color maps. 233
And here you can find the names and the look of various different types of color maps. 234
So for example one of the color maps is called plasma. 235
So if I update my code here to "cm.plasma" then I'll get a color map that looks like this on my 236
chart. 237
But of course you're not limited to this. 238
You can also try, I don't know, "winter" or "hot" see what those look like. "cm.winter" will give us this 239
look and "cm.hot" will give us this look right here. 240
Now if Google didn't bring you to this page then perhaps you landed on this page instead - the "colormaps_ 241
reference.py" documentation. 242
And here you'll also see very, very similar information - you'll get a visual representation of various 243
different color maps that are available. 244
So either of these two pages from matplotlib.org will give you the information that you need to 245
find the right color map to suit your preferences.