Hi, welcome back. In this video, we are
going to create an average rating by
month by course graph. As you may know,
we created that graph already but
using Jupyter and matplotlib. So it
look like this. The idea is that we're
going to have the Month in the
horizontal axis, and Average Ratings on
the vertical axis, and we're going to
have multiple graphs in that plot area,
each representing a course in our dataset.
And as you may know already, a
good way to create graphs using JustPy
and Highcharts is to go to the
highcharts.com website, so you go under
Charts and series types, and we find a
graph that would be a good
representative of our data. So I took a
look in these examples, and I found that
I would like to use Areaspline chart,
which looks like this. You see that this
has multiple lines, so 2 in this case,
and it has this x axis with categorical
data. So it's not numbers, it's Monday,
Tuesday, Wednesday, and so on, and we
have this number y axis, so Fruits
units, and it represents the average
fruit consumption during one week for
John and Jane. In our case, we are going
to change this graph and have six or
seven lines, I'm not sure how many
courses there are. So one line for each
course showing the average ratings a
long time, so over the months. So before
we copy the code, let's first prepare
the environment. So create the script
and create the JustPy app, and so on.
So I'm going to name this 4-average-rating,
this will be, let's say, course-month,
so average rating by course by
month, '.py'. You see that is
different from average-rating-month,
this is average rating by course by
month. Right? Now I'm going to copy this
template of JustPy, copy there.
[No audio]
hc will be the HighCharts component, which
belongs to wp and options is going to be
as usually chart_definition, which has
to be a variable somewhere here
[No audio]
is equal to a string, a multi-line string.
[No audio]
So let us copy that JavaScript code.
[No audio]
So this one in here, I'm going to copy all of that,
paste it in there, and then just before
chart, we leave that curly bracket
before chart here, we leave that, and
delete the semicolon, and the
parenthesis. And now we are ready to
replace these data with our data.
But what I suggest you do first is to
try out this example to see if this is
working right now, without changing the
data with your own data. So what I would
like to do now is try to run this
[No audio]
and then visit the URL, and you're going to
see an error. So JSONDecodeError
Unknown identifier Highcharts. This
happens because of this line. Python
cannot recognize this expression here
because this is JavaScript. So you want
to delete that and only leave this
string here, the color of background
color, and now, if I stop the script,
and run again, and reload the page, we
should see the example just like we got
it from the Highcharts website. Now
these two graphs are areasplines. But
if you want to change them to spline,
you want to go over to your code and
change that areaspline to spline, stop
the script, run again,
[No audio]
and reload,
and this is the output. Now we are
ready to inject our own data into these
data. So for that we want to go over to
Jupyter where we have our analysis
ready, copy that code,
[No audio]
paste it there,
and we also need to do the aggregations
necessary for extracting the month, the
courses by month, so which is this code
here, and that gives us this DataFrame.
Now let's refresh our memory how the
DataFrame looked like. So you can
either print them in here
[No audio]
and execute the scripts, reload the page and see
what you got printed out in the
terminal, or you can see the outputs
from Jupyter. So whatever you prefer,
I'm just going to execute the script here.
[No audio]
And so we get the DataFrame printed out, even
before we load the web app because
it printed out because the web app is
inside of functions. So this is just in
the global namespace, in the global
scope. So when the script is executed,
these are executed. If this was inside
the function here, it would only be
executed when we load the page, and
here, this is the DataFrame, so it has
this Month index, and it has different
columns. So this is the first column, then
we have more columns, which we don't see
in here, and then the last column is
this, and the values of each column, so
the name of a column, the values of that
column, which have the average ratings, and
we have one month for each row. So this
is July of 2019, August 2019,
[No audio]
and January 2020, and so on.
So index columns. Let's see now,
[No audio]
how do we inject
those data into these data?
[No audio]
So we see that xAxis has this categories
with these weekdays, so we can do the same
thing now. Down here, we
say hc.options.xAxis, so
xAxis is the
[No audio]
key of the main
dictionary, so it's directly exposed in the
first level, so chart, title, legend,
Axis, and then we have the second level,
so categories is part of Axis, therefore
we can access it, like so. So categories
is a list, as you can see here,
therefore, we need to replace it with a
list, list month_average_crs, so that
is our DataFrame, '.index'. So
that column in there, 2018-05, 2018-06,
and so on, right. That was the
easy part. Now comes the data. So, what
you need to do is you need to understand
the structure of the data that is the
very important first step. And so series is
a first level key, therefore, we can
say, hc.options.series,
right. So this will give us that list.
Then that list has, how many items does
it have? So I see a dictionary, from
there, upto here, that's a dictionary
that has this name, John, pair of key
and values name is the key, John is
value, then we have this other key data,
and a list and the dictionary ends there, and
then we have the other dictionary. So
it's Jane now, and these are the data
for Jane. So the list is made of
dictionary, and each dictionary
represents a line in that chart. So
that's for Jane, and that's for John.
Therefore, what we need to do is we need
to have here, so that would be the name
of a course. Let's say the first course would be
[No audio]
100 Python Exercises 1 and
so on, the entire title, and then data
would contain a list of average ratings
for that particular course. So that
one, that one, that one, and so on.
And then we would have to repeat
that process for each of the six or seven
courses that we have here. How do we do
that? Well, you could do that manually,
like maybe you could inject. So from
series, you would say
[No audio]
the first plot,
so that would give you the first
dictionary, that expression is the first
dictionary and then we could access name
and replace that to maybe the
month_average_crs.columns. So that would
be the first column, and so on, that
would be okay. But it's not an automatic
process. So when you do manual work,
that is a sign that you're not doing
programming the right way, what we need
to do instead is we need to create this
entire list dynamically. And this is a very,
very crucial point now in using
Highcharts, but also in knowing how to
manipulate data structures in Python. So
this is an excellent practice, I'm
very glad this came out such a
great practice for you. So let me show
you how you can construct this list out
of this DataFrame. And so before we do
that, before we assigned the list, we
want to construct the list. So let's
name this hc_data, and that is
equal to, so we need to create a list. So
that is a list. Therefore, we write
square brackets. The list is made of
dictionaries, therefore, we'll write
curly brackets, and then inside each
dictionary, we have a name key, we
always have that name key, and a
variable for that name key. Why I'm
saying variable? Well, because name is
always name, so it's a constant. That's
why I'm hard coding that. So we should
always have name there, but the value of
name is a variable, so it's changing
every time. And then what else, we
have that pair, okay, inside the
dictionary, that dictionary, so that
dictionary has another pair, so data
and the list. So let's write that a
comma, data, the string, a colon, and
we have a list. That list is basically
representative of each of the plots, each
of the seven plots that we are going to
have for each course. So which means
that list is going to be these ratings.
For example, we're going to have the
first list being the first column, for
example, for 100 Python Exercises 1
for that course, this column as a list
in there, and then the other column
after that course, the next and the next
and the next. So one column for each
course, and v1 is going to be
replaced by the title of the column. So
before I write the expression inside
this list, I want to finish first, the
upper level list comprehension because
we have two list comprehensions here,
we have the first level one, so let's
call it the upper level. Here we are
constructing dictionaries
so its a list made of dictionaries, so
that means we should say, here, for
v1 in month_average_crs.columns.
So what that is, is a list
containing seven strings, one string
for each course title. So it's going to
be a list containing a 100 Python
Exercises 1 Evaluate and Improve Your
Skills, then the other title of the
other course, and so on, it's a list of
these titles. So what we're doing is we
are injecting here, a title, the first
title of that list in the first
iteration, then the next title of that
month_average_crs.columns lists in the
next iteration, and so on. We're going to
have like seven iterations or six,
whatever is the number of courses that
we have, right. But then inside here, we
have a nested iteration, a nested list
comprehension, sorry, which is this one
here, and that will be again, let's
write another variable, such as v2,
for v2
in month_average_crs,
hmm, so what is this going to be? Well,
it has to be this column, right? So
which one is this column?
What's the name of this column? Well,
for this course is that is the name of
the column. So here we need to write
down the name of the column. You see
this is a Pandas syntax. So you write
the name of the column but we have
different column names. So what's we
enter here then is v1, because v1
is going to be the current title in the
upper level list comprehension. So
basically what Python will do is, while
it is iterating, the first title, it's
going to stop in that upper level, first
iteration, and it's going to iterate
through that particular column, through
these ratings for 100 Python Exercises 1,
and it will construct that list.
Once it finishes with all these numbers,
it constructs that list, then it goes to
the other, to the second iteration in
the first level iteration. So in the
second iteration of the other columns,
which is going to be the next course,
and so on. I hope it's clear. Right, so
what's left to do is, we need to assign
these new list so to inject it to our
data, because we created it, but we
haven't connected it to hc. So it
just a variable floating there in our
script, not connections to the other
parts. So what we need to do is, we said
that, that one, that list is that a
list. So we need to assign it to series,
right. hc.options.series
equal to hc.data. Right. Now, I'm
going to stop the script and run and
visit the app, and this is the output.
Here is the x axis with the Month and this
is our Ratings, so from 2.5 upto 5.5.
The maximum is somewhere in here. So you
can hover the mouse there, and you see
the ratings for each course. Right. The
legend here is floating. So if you want
to change that, you can go back to your
code and locate the legends here. So you
have some parameters here, which you can
experiment with. But if I set floating to false
[No audio]
that should change the view of
a graph. So I think this is more clear.
Now, I wouldn't agree that this type of
graph is the best representation for
these kinds of data because we have
multiple lines here. But they are so
close to each other. So there's no much
variations between one course and the
other. I think these splines would be
more representative if we had, instead
of averages, we have the count of the
reviews of the ratings left for each
course, which means we have to go to the
processing section and say here count
instead of mean, and let me try that.
[No audio]
So yeah, it looks better I think. We
have more variation, more difference
between of this plot and the other
ones. Although the other ones
are still not as visible since this plot
here is taking a lot of the range of the
y axis range. Therefore, what I'm
going to do next in the next video is
I'm going to use another type of graph
to represent the same, the exact same data,
average ratings by course by months but
using a stream graph. I'll talk to you
in the next video.