From e306dffe7f6c2bf61a250ac77b456e2e0a8a3a8e Mon Sep 17 00:00:00 2001 From: Saransh Chopra Date: Tue, 20 Aug 2024 09:32:34 +0100 Subject: [PATCH] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: David Pérez-Suárez --- ch02data/062basic_plotting.ipynb.py | 4 ++-- ch02data/066QuakeExercise.ipynb.py | 6 +++++- ch02data/068QuakesSolution.ipynb.py | 23 +++++++++++++++++++---- ch02data/082NumPy.ipynb.py | 3 ++- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/ch02data/062basic_plotting.ipynb.py b/ch02data/062basic_plotting.ipynb.py index 40006d8b..debffeb5 100644 --- a/ch02data/062basic_plotting.ipynb.py +++ b/ch02data/062basic_plotting.ipynb.py @@ -14,7 +14,7 @@ # %% [markdown] # # Plotting with Matplotlib - the `pyplot` interface # -# [Matplotlib](https://matplotlib.org/) is a Python library which can be used to produce plots to visualise data. It has support for a wide range of [different plot types](https://matplotlib.org/stable/gallery/index.html), and as well as supporting static outputs it also allows producing [animations](https://matplotlib.org/stable/api/animation_api.html) and [interactive plots](https://matplotlib.org/stable/gallery/index.html#event-handling). As an intial introduction, we will demonstrate how to use Matplotlib's [`pyplot` interface](https://matplotlib.org/stable/api/index.html#the-pyplot-api) (modelled on the plotting functions in MATLAB), to create a simple line plot. If you return for our more advanced course we will illustrate Matplotlib's [object-oriented interface](https://matplotlib.org/stable/api/index.html#id3) which allows more flexibility in creating complex plots and greater control over the appearance of plot elements. +# [Matplotlib](https://matplotlib.org/) is a Python library which can be used to produce plots to visualise data. It has support for a wide range of [different plot types](https://matplotlib.org/stable/gallery/index.html), and as well as supporting static outputs it also allows producing [animations](https://matplotlib.org/stable/api/animation_api.html) and [interactive plots](https://matplotlib.org/stable/gallery/index.html#event-handling). As an intial introduction, we will demonstrate how to use Matplotlib's [`pyplot` interface](https://matplotlib.org/stable/api/index.html#the-pyplot-api) (modelled on the plotting functions in MATLAB), to create a simple line plot. Later, we will then illustrate Matplotlib's [object-oriented interface](https://matplotlib.org/stable/api/index.html#id3) which allows more flexibility in creating complex plots and greater control over the appearance of plot elements. # # ## Importing Matplotlib # @@ -32,7 +32,7 @@ plt.plot([2, 4, 6, 8, 10], [1, 5, 3, 7, -11]) # %% [markdown] -# The `plt.plot` function allows producing line and scatter plots which visualize the relationship between pairs of variables. Here we pass `plt.plot` two lists of five numbers corresponding to respectively the coordinates of the points to plot on the horizontal (*x*) axis and the coordinates of the points to plot on the vertical (*y*) axis. When passed no other arguments by default `plt.plot` will produce a line plot passing through the specified points. The value returned by `plt.plot` is a list of objects corresponding to the plotted line(s): in this case we plotted only one line so the list has only one element. We will for now ignore these return values until we cover object-oriented programminga and return to explain Matplotlib's object-oriented interface. +# The `plt.plot` function allows producing line and scatter plots which visualize the relationship between pairs of variables. Here we pass `plt.plot` two lists of five numbers corresponding to respectively the coordinates of the points to plot on the horizontal (*x*) axis and the coordinates of the points to plot on the vertical (*y*) axis. When passed no other arguments by default `plt.plot` will produce a line plot passing through the specified points. The value returned by `plt.plot` is a list of objects corresponding to the plotted line(s): in this case we plotted only one line so the list has only one element. We will for now ignore these return values, we will return to explain Matplotlib's object-oriented interface in a later episode. # # If passed a single list of numbers, the `plt.plot` function will interpret these as the coordinates of the points to plot on the vertical (*y*) axis, with the horizontal (*x*) axis points in this case implicitly assumed to be the indices of the values in the list. For example, if we plot with just the second list from the previous `plt.plot` call diff --git a/ch02data/066QuakeExercise.ipynb.py b/ch02data/066QuakeExercise.ipynb.py index 61f24086..473e92cd 100644 --- a/ch02data/066QuakeExercise.ipynb.py +++ b/ch02data/066QuakeExercise.ipynb.py @@ -35,7 +35,7 @@ # %% jupyter={"outputs_hidden": false} query_parameters = { "format": "geojson", - "starttime": "2000-01-01", + "starttime": "2001-01-01", "maxlatitude": "60.830", "minlatitude": "49.877", "maxlongitude": "1.767", @@ -84,3 +84,7 @@ # * Find the place of the biggest quake. # * Form a URL for a map tile centered at that latitude and longitude (look back at the introductory example). # * Display that map tile image. +# +# A couple of suggestions on how to tackle this exercise: +# - make a smaller query (for example setting up the `endtime` parameter to only query a year), and +# - open the result url `quakes_response.url` with the Firefox browser to easily understand the file structure. diff --git a/ch02data/068QuakesSolution.ipynb.py b/ch02data/068QuakesSolution.ipynb.py index 3805ecb1..4573b674 100644 --- a/ch02data/068QuakesSolution.ipynb.py +++ b/ch02data/068QuakesSolution.ipynb.py @@ -19,8 +19,9 @@ # We first import the modules we will need to get and plot the data. We will use the `requests` module to query the USGS earthquake catalog, the `math` module to do some coordinate conversion and the `IPython` module to display a map image. # %% jupyter={"outputs_hidden": false} -import requests import math + +import requests import IPython from IPython.display import Image @@ -33,7 +34,7 @@ earthquake_catalog_api_url = "http://earthquake.usgs.gov/fdsnws/event/1/query" query_parameters = { "format": "geojson", - "starttime": "2000-01-01", + "starttime": "2001-01-01", "maxlatitude": "60.830", "minlatitude": "49.877", "maxlongitude": "1.767", @@ -166,12 +167,26 @@ # # Now that we have a handle on the structure of the data, we are ready to search through the data to identify the largest magnitude earthquake event(s). We are interested in finding the element (or elements) in a sequence which maximises some property - this operation is termed the [$\arg\max$ in mathematics and computer science](https://en.wikipedia.org/wiki/Arg_max). While there is built-in `max` function in Python there is no corresponding `argmax` function, though several external libraries including the NumPy library which we encounter in a subsequent lesson do include an `argmax` function. # +# As a first approach, we will set the first eartquake to be the largest and as we iterate over the others we will replace the first one with whatever is larger. + +# %% +quakes = requests_json['features'] + +largest_so_far = quakes[0] +for quake in quakes: + if quake['properties']['mag'] > largest_so_far['properties']['mag']: + largest_so_far = quake +largest_so_far['properties']['mag'] + +# %% [markdown] +# Great, this gives us the largest earthquake... but, what if there were multiple earthquakes with the same magnitude? +# Can we know it from the above result? # We will therefore loop over all of the event details in the `features` list and construct a list of the event or events for which the magnitude is currently the largest, creating a new list if the magnitude of the current event is larger than the previous largest or adding the event to the previous list if it has an equal magnitude. After iterating through all the events this list should contain the details of the event(s) with the largest magnitude. An example implementation of this approach is as follows. # %% jupyter={"outputs_hidden": false} -largest_magnitude_events = [quakes_json['features'][0]] +largest_magnitude_events = [quakes[0]] -for quake in quakes_json['features']: +for quake in quakes: if quake['properties']['mag'] > largest_magnitude_events[0]['properties']['mag']: largest_magnitude_events = [quake] elif quake['properties']['mag'] == largest_magnitude_events[0]['properties']['mag']: diff --git a/ch02data/082NumPy.ipynb.py b/ch02data/082NumPy.ipynb.py index 3339a7a2..e21894ad 100644 --- a/ch02data/082NumPy.ipynb.py +++ b/ch02data/082NumPy.ipynb.py @@ -20,8 +20,9 @@ # # MATLAB has typically been the most popular "language of technical computing", with strong built-in support for efficient numerical analysis with matrices (the *mat* in MATLAB is for matrix, not maths), and plotting. # -# Other dynamic languages can be argued to have cleaner, more logical syntax, for example [Ruby](https://www.ruby-lang.org/en/) or [Scheme][scheme]. +# Other dynamic languages can be argued to have cleaner, more logical syntax, for example [Ruby][ruby] or [Scheme][scheme]. # +# [ruby]: https://www.ruby-lang.org/en/ # [scheme]: https://en.wikipedia.org/wiki/Scheme_(programming_language) # But Python users developed three critical libraries, matching the power of MATLAB for scientific work: #