Verified Commit c8f0e34f authored by Renato Alves's avatar Renato Alves 🌱
Browse files

Add colourmaps and move some exercises around

parent 44119e7c
......@@ -663,64 +663,31 @@ style, disables drawing a connecting line.
> {: .solution }
{: .challenge }
> ## Formatting Data Points
>
> 1. Fill in the blanks in the function definition below
> so that the colour of the circles represents the continent
> that country belongs to.
>
> Note that the approach below uses
> a list comprehension to define a colour to represent each continent,
> and `*` to unpack the tuple returned
> by `get_year_data` (the function we defined in the previous exercise).
> You may wish to check back to the earlier sections on
> [comprehensions](../01-syntax/index.html#comprehensions)
> [expanding arguments outside functions](../01-syntax/index.html#argument-expansion-outside-functions)
> to remind yourself of what is happening here.
>
> ~~~
> from matplotlib import cm
>
> continents = list(gapminder['continent'].unique())
> continent_colors = [cm.Set2.colors[continents.index(c)] for ___ in gapminder[___]]
>
> fig, ax = plt.subplots()
> ax.scatter(*get_year_data(gapminder, 2002), ____, alpha=0.75)
> ax.set_title('2002')
> ax.set_xscale('log')
> ax.set_xlabel('GDP per capita (USD)')
> ax.set_ylabel('Life expectancy (years)')
> ~~~
> {: .language-python }
>
> 2. What is the `alpha` argument doing in the `ax.scatter` call above?
> Try adjusting the value to see what effect this has.
>
> > ## Solution
> >
> > ~~~
> > # 1
> > continents = list(gapminder['continent'].unique())
> > continent_colors = [cm.Set2.colors[continents.index(cont)] for cont in gapminder['continent']]
> >
> > fig, ax = plt.subplots()
> > ax.scatter(*get_year_data(gapminder, 2002), c=continent_colors, alpha=0.75)
> > ax.set_title('2002')
> > ax.set_xscale('log')
> > ax.set_xlabel('GDP per capita (USD)')
> > ax.set_ylabel('Life expectancy (years)')
> > ~~~
> > {: .language-python }
> >
> > 2: `alpha` controls the transparancy of the plotted data points.
> > A value of 1 makes the points opaque, 0 makes them invisible
> > (fully transparent).
> > For a plot like this,
> > with many overlapping points of varying size,
> > some transparency is helpful to get a complete understanding of the
> > distribution of points.
> {: .solution }
{: .challenge }
### Colormaps
When plotting data, it is often convenient to use
a color scales, be them continuous or discrete.
Also known as gradient scales, or in matplotlib, colormaps,
this feature simplifies the process of mapping values to color.
There are several considerations when choosing a colormap
depending on the type of data and the purpose of the visualization.
Some of the theory is visually illustrated in the [colormap documentation][matplotlib-colormaps].
To map values to a colormap, you need simply to pass the values to the colormap
object and it will return colors for each point.
~~~
# also available as matplotlib.pyplot.cm or plt.cm
from matplotlib import cm
x = np.linspace(0, 2, 50)
plt.scatter(x, x**3, color=cm.viridis(x**3))
~~~
{: .language-python }
![colormap example](../fig/colormap-example.png)
### Histograms
......@@ -982,14 +949,31 @@ Which looks great, but something unexpected happened in the stacked subplot.
> {: .solution}
{: .challenge}
## Others plots
# Axis
## Log axis
## Radial axis
> ## More plotting and drawing tools
>
> Besides the plot variants mentioned above, Matplotlib can also produce
> `pie charts`,
> `box plots`,
> `contour maps`,
> `stream plot`
> `heatmaps/hexbin`,
> `geomaps`,
> and [many others](https://matplotlib.org/3.2.2/tutorials/introductory/sample_plots.html), some [composed manually][matplotlib-gallery] and others via
> [third-party extensions](https://www.machinelearningplus.com/plots/top-50-matplotlib-visualizations-the-master-plots-python/).
>
> If you want to add highlights to your plot in the form of arrows,
> countours, text or other graphical elements, matplotlib can perform
> all that and more, using [annotations][matplotlib-annotate].
>
> You can also affect how data is displayed by
> setting each axis to have an implicit data transformation.
> Matplotlib offers different types of logarithms as illustrated
> in the [log demo](https://matplotlib.org/3.2.2/gallery/scales/log_demo.html),
> or using different projections such as
> [polar coordinate system](https://matplotlib.org/examples/pylab_examples/polar_demo.html) or
> [geographical projections](https://matplotlib.org/3.2.1/gallery/subplots_axes_and_figures/geo_demo.html).
[: .callout]
# Changing style
## Color maps
# Plotting from pandas
......@@ -1180,7 +1164,8 @@ it is assumed that string values like these will refer to columns inside the
> ## Other plotting methods
>
> In addition to the `kind`s of plot we can produce with `.plot`
> Much like in matplotlib, pandas can produce different `kind`s of plots
> besides those via `.plot()`
> (the full list is:
> `area`,
> `bar`,
......@@ -1235,6 +1220,112 @@ it is assumed that string values like these will refer to columns inside the
> {: .solution }
{: .challenge }
> ## Formatting Data Points
>
> 1. Fill in the blanks in the function definition below
> so that the colour of the circles represents the continent
> that country belongs to.
>
> Note that the approach below uses
> a list comprehension to define a colour to represent each continent,
> and `*` to unpack the tuple returned
> by `get_year_data` (the function we defined in the previous exercise).
> You may wish to check back to the earlier sections on
> [comprehensions](../01-syntax/index.html#comprehensions)
> [expanding arguments outside functions](../01-syntax/index.html#argument-expansion-outside-functions)
> to remind yourself of what is happening here.
>
> ~~~
> from matplotlib import cm
>
> continents = list(gapminder['continent'].unique())
> continent_colors = [cm.Set2.colors[continents.index(c)] for ___ in gapminder[___]]
>
> fig, ax = plt.subplots()
> ax.scatter(*get_year_data(gapminder, 2002), ____, alpha=0.75)
> ax.set_title('2002')
> ax.set_xscale('log')
> ax.set_xlabel('GDP per capita (USD)')
> ax.set_ylabel('Life expectancy (years)')
> ~~~
> {: .language-python }
>
> 2. What is the `alpha` argument doing in the `ax.scatter` call above?
> Try adjusting the value to see what effect this has.
>
> > ## Solution
> >
> > ~~~
> > # 1
> > continents = list(gapminder['continent'].unique())
> > continent_colors = [cm.Set2.colors[continents.index(cont)] for cont in gapminder['continent']]
> >
> > fig, ax = plt.subplots()
> > ax.scatter(*get_year_data(gapminder, 2002), c=continent_colors, alpha=0.75)
> > ax.set_title('2002')
> > ax.set_xscale('log')
> > ax.set_xlabel('GDP per capita (USD)')
> > ax.set_ylabel('Life expectancy (years)')
> > ~~~
> > {: .language-python }
> >
> > 2: `alpha` controls the transparancy of the plotted data points.
> > A value of 1 makes the points opaque, 0 makes them invisible
> > (fully transparent).
> > For a plot like this,
> > with many overlapping points of varying size,
> > some transparency is helpful to get a complete understanding of the
> > distribution of points.
> {: .solution }
{: .challenge }
> ## Adding to Plots
>
> 1. Building on the code example above, add a second line showing the daily cases reported in Germany. This line should be plotted behind the rolling mean line.
> 2. Once you've done this, adjust the formatting (colour, line width, etc) of the rolling mean line to make it stand out.
> 3. Wrap all of this code as a function definition, so that the user can provide the name of a country for which to plot this data.
>
> > ## Solution
> >
> > ~~~
> > # 1
> > fig, ax = plt.subplots()
> > de_cases = combined[combined['countriesAndTerritories'] == 'Germany']['cases']
> > de_cases.index = combined[combined['countriesAndTerritories'] == 'Germany']['dateRep']
> > ax.plot(de_cases)
> > ax.plot(de_rolling)
> > ax.set_title('Germany')
> > ax.set_ylabel('cases')
> > fig # or 'fig' if using Jupyter
> >
> > # 2
> > fig, ax = plt.subplots()
> > de_cases = combined[combined['countriesAndTerritories'] == 'Germany']['cases']
> > de_cases.index = combined[combined['countriesAndTerritories'] == 'Germany']['dateRep']
> > ax.plot(de_cases)
> > ax.plot(de_rolling, color='red', linewidth=2.5)
> > ax.set_title('Germany')
> > ax.set_ylabel('cases')
> > fig.show()
> >
> > # 3
> > def plot_cases(df, 'country'):
> > fig, ax = plt.subplots()
> > filter_mask = df['countriesAndTerritories'] == country
> > cases = df[filter_mask]['cases']
> > rolling_mean = df[filter_mask]['rolling mean']
> > cases.index = rolling_mean.index = df[filter_mask] == country]['dateRep']
> > ax.plot(cases)
> > ax.plot(rolling_mean)
> > ax.set_title(country)
> > ax.set_ylabel('cases')
> > return fig
> > ghana_plot = plot_cases(combined, 'Ghana') # testing that the function works
> > ~~~
> > {: .language-python }
> {: .solution }
{: .challenge }
# Where to go from here
## The Matplotlib Gallery
......@@ -1306,54 +1397,7 @@ These widgets really shine when you want to have a flexible and interactive
way to experiment with different thresholds,
perhaps while showing your latest results to your colleagues.
# Exercises
> ## Adding to Plots
>
> 1. Building on the code example above, add a second line showing the daily cases reported in Germany. This line should be plotted behind the rolling mean line.
> 2. Once you've done this, adjust the formatting (colour, line width, etc) of the rolling mean line to make it stand out.
> 3. Wrap all of this code as a function definition, so that the user can provide the name of a country for which to plot this data.
>
> > ## Solution
> >
> > ~~~
> > # 1
> > fig, ax = plt.subplots()
> > de_cases = combined[combined['countriesAndTerritories'] == 'Germany']['cases']
> > de_cases.index = combined[combined['countriesAndTerritories'] == 'Germany']['dateRep']
> > ax.plot(de_cases)
> > ax.plot(de_rolling)
> > ax.set_title('Germany')
> > ax.set_ylabel('cases')
> > fig.show() # or 'fig' if using Jupyter
> >
> > # 2
> > fig, ax = plt.subplots()
> > de_cases = combined[combined['countriesAndTerritories'] == 'Germany']['cases']
> > de_cases.index = combined[combined['countriesAndTerritories'] == 'Germany']['dateRep']
> > ax.plot(de_cases)
> > ax.plot(de_rolling, color='red', linewidth=2.5)
> > ax.set_title('Germany')
> > ax.set_ylabel('cases')
> > fig.show()
> >
> > # 3
> > def plot_cases(df, 'country'):
> > fig, ax = plt.subplots()
> > filter_mask = df['countriesAndTerritories'] == country
> > cases = df[filter_mask]['cases']
> > rolling_mean = df[filter_mask]['rolling mean']
> > cases.index = rolling_mean.index = df[filter_mask] == country]['dateRep']
> > ax.plot(cases)
> > ax.plot(rolling_mean)
> > ax.set_title(country)
> > ax.set_ylabel('cases')
> > return fig
> > ghana_plot = plot_cases(combined, 'Ghana') # testing that the function works
> > ~~~
> > {: .language-python }
> {: .solution }
{: .challenge }
# Additional challenges
> ## The coffee stain
>
......
......@@ -85,10 +85,12 @@
[logging]: https://docs.python.org/3/library/logging.html
[markdown-cheatsheet]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet
[matlab-home]: https://www.mathworks.com/products/matlab.html
[matplotlib-annotate]: https://matplotlib.org/tutorials/text/annotations.html
[matplotlib-backends]: https://matplotlib.org/tutorials/introductory/usage.html#the-builtin-backends
[matplotlib-books]: https://matplotlib.org/resources/index.html
[matplotlib-color-codes]: https://matplotlib.org/3.2.2/tutorials/colors/colors.html
[matplotlib-color-names]: https://matplotlib.org/3.2.2/gallery/color/named_colors.html
[matplotlib-colormaps]: https://matplotlib.org/3.3.0/tutorials/colors/colormaps.html
[matplotlib-colors]: https://matplotlib.org/3.2.2/api/colors_api.html
[matplotlib-gallery]: https://matplotlib.org/gallery/index.html
[matplotlib-gridspec-example]: https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/gridspec_multicolumn.html
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment