diff --git a/book/_toc.yml b/book/_toc.yml
index e8a79d6..c536dd3 100644
--- a/book/_toc.yml
+++ b/book/_toc.yml
@@ -39,6 +39,6 @@ parts:
- file: notebooks/4a_bound_long_wave
- file: notebooks/4b_shallow_water_tides
- - caption: Week 5
- chapters:
- - file: notebooks/coastal_impact_beach_states
+ - caption: Week 4
+ chapters:
+ - file: notebooks/5_coastal_impact_beach_states
diff --git a/book/notebooks/5_coastal_impact_beach_states.ipynb b/book/notebooks/5_coastal_impact_beach_states.ipynb
new file mode 100644
index 0000000..2e00d24
--- /dev/null
+++ b/book/notebooks/5_coastal_impact_beach_states.ipynb
@@ -0,0 +1,676 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "968bd444-a7c0-44f6-8648-60b84b483abf",
+ "metadata": {},
+ "source": [
+ "## First import some necessary packages"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7d6f5660-3939-4d95-b5bd-79b770efb391",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import logging\n",
+ "import os\n",
+ "import pathlib\n",
+ "import warnings\n",
+ "\n",
+ "import bokeh.io\n",
+ "import colorcet as cc\n",
+ "import geopandas as gpd\n",
+ "import holoviews as hv\n",
+ "import hvplot.pandas # noqa: API import\n",
+ "import ipyleaflet\n",
+ "import IPython\n",
+ "import ipywidgets as widgets\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import panel as pn\n",
+ "from bokeh.models import HoverTool, PanTool, WheelZoomTool\n",
+ "from bokeh.resources import INLINE\n",
+ "from IPython.display import HTML, display\n",
+ "\n",
+ "import coastal_dynamics as cd\n",
+ "\n",
+ "# Silence DeprecationWarning # Future TODO: in spring 2024 rm this silence and check status\n",
+ "with warnings.catch_warnings():\n",
+ " warnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n",
+ " import dask.dataframe as dd\n",
+ "\n",
+ "# Activate Panel extension to make interactive visualizations\n",
+ "pn.extension()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "95265f6d-c208-4b3c-b255-5fa11459993c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# # Read questions from cloud storage\n",
+ "questions = cd.read_questions(\n",
+ " \"az://coastal-dynamics/questions/5_coastal_impact_beach_states_hashed.json\",\n",
+ " storage_options={\"account_name\": \"coclico\"},\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4cc2af60-3591-4acb-8acf-8e55443806b0",
+ "metadata": {},
+ "source": [
+ "In this notebook you might encounter some 'FutureWarning' or 'PanelDeprecationWarning'. This is the result of using an old version of the holoviews package. These messages can safely be ignored. If you want to get rid of these messages, you can update the holoviews package using the code cell below (uncommented!)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "94581fc2-5e13-4122-902a-5a0e0f0abe0c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# !pip install --upgrade holoviews"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0ab15b81-15ce-4f27-8f82-04338a14cfb9",
+ "metadata": {},
+ "source": [
+ "# Morphodynamics of the upper shoreface\n",
+ "Welcome to the notebook of week 5! The main topic of this notebook is beach states (section 7.3 in the book). These are discussed also in the context of coastal classification (chapter 2 in the book). This notebook consists of the following sections:\n",
+ "* Coastal classification\n",
+ "* Beach states\n",
+ "\n",
+ "Each section contains questions for you to practice with (cross-shore) sediment transport. Let's get started!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "af8b08d4-5d25-43a0-95ad-d7d7f3a2a43e",
+ "metadata": {},
+ "source": [
+ "## Coastal classification\n",
+ "As you know from chapter 2 of the book and the week 1 notebook, coasts can be classified based on tectonics and processes. In this notebook we will look at different Brazilian coastal systems, and try to classify them. Let's start with loading the dataset with data for the Brazilian coastline. This dataset contains the significant wave height (Hs), the peak period (T), the mean tidal range (MTR), the shoreface slope, and other useful values for different coordinates along the Brazilian coast. This dataset is adapted from:\n",
+ "* Athanasiou et al. (2023) -- https://zenodo.org/records/8200200\n",
+ "* Klein et al. (2016) -- https://link.springer.com/book/10.1007/978-3-319-30394-9\n",
+ "* Matias et al. (2009) -- https://www.researchgate.net/publication/235951526_Sediment_Dynamics_of_Barriers_with_Frequent_Overwash\n",
+ "\n",
+ "Specifically, the first source is used to get values for Hs, T and MTR. The second source is used to get the RTR, D and the beachface slope for the Santa Catarina, Maranhao, and Rio de Janeiro provinces. The third source is used to get the RTR, D and the beachface slope for the Rio de Janeiro province.\n",
+ "\n",
+ "Since this dataset is aggregated from multiple sources, the accuracy of its content at a local scale should be critically interpreted. Athanasiou et al. (2023) for example use a numerical model to compute offshore wave data, whereas Klein et al. (2009) use direct measurements. All of this is to say that this data is not presumed to be locally accurate. However, in this context, we use it to compare the Brazilian coastline on a larger regional scale and draw broad conclusions to illustrate the concepts introduced in this course."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b055bd77-1eb2-4312-8ae7-280b7c40d96f",
+ "metadata": {},
+ "source": [
+ "### Load data\n",
+ "The cell below loads the data from the cloud. The first 5 entries are shown using the .head() method, so you can see what the dataframe looks like!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "88beaa75-eb1c-4434-bb04-f11ed63c8ec0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pooch\n",
+ "\n",
+ "fp = pooch.retrieve(\n",
+ " \"https://coclico.blob.core.windows.net/coastal-dynamics/5_coastal_impact_beach_states/5_data.gpkg\",\n",
+ " known_hash=\"661ddc9ad6a396dd6fe9a9cf2126a32b1134fef92075fa19f5ee1ee445125934\",\n",
+ ")\n",
+ "\n",
+ "# We load this file as a GeoDataFrame, which comes with a column containing the geometry of each entry. For this dataset, these are points (longitude, latitude)\n",
+ "gdf = gpd.read_file(fp)\n",
+ "\n",
+ "\n",
+ "def convert_to_numeric(value):\n",
+ " if pd.isnull(value):\n",
+ " return np.nan # Convert None to NaN\n",
+ " if value.startswith(\">\"):\n",
+ " epsilon = 0.1 # Define how much greater\n",
+ " return float(value[1:])\n",
+ " elif value.startswith(\"~\"):\n",
+ " return float(value[1:])\n",
+ " else:\n",
+ " return float(value)\n",
+ "\n",
+ "\n",
+ "gdf[\"Omega [-]\"] = gdf[\"Omega [-]\"].apply(convert_to_numeric)\n",
+ "\n",
+ "gdf.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "824fb13d-a4aa-44c1-9729-2a4e61f3e72a",
+ "metadata": {},
+ "source": [
+ "In this dataframe the fall velocity w_s was calculated using other values from the dataset. It was calculated using Soulsby (1997). You don't have to remember this equation, but it is included here for completeness:\n",
+ "$$ w_s = (\\nu_{kin} / D) * \\left( \\sqrt{10.36^2 + 1.049 * (D_{*}^3)} - 10.36 \\right) $$\n",
+ "with\n",
+ "$ D_{*} = \\left(\\frac{g * (\\rho_s / \\rho_w - 1)}{\\nu_{kin}^2}\\right) ^{1/3} * D $, $g=9.81$ m/s$^2$, $\\nu_{kin}=1.36e-6$ m$^2$/s, $\\rho_w=1027$ kg/m$^3$, $\\rho_s=2650$ kg/m$^3$\n",
+ "\n",
+ "The dimensionless fall velocity can be calculated using equation 7.8 from the book:\n",
+ "$$ \\Omega = \\frac{H_b}{w_s T} $$\n",
+ "We did some preliminary calculations, and the Omega values as presented in the dataset should be sufficient for qualitatively comparing different coastal systems.\n",
+ "\n",
+ "Again, we would like to stress that the values should not be interpreted as highly accurate for specific beaches. They are just useful to get a feel for the surrounding area and to get first estimates of the order of magnitude."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f368461c-08f8-4e2e-b722-9d003559d035",
+ "metadata": {},
+ "source": [
+ "### Define plot function\n",
+ "\n",
+ "**Note**: Although you don't have to understand the plot method, we include it here so you can see how these interactive plots are made! !"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b2dd9273-ff8e-40ef-bcc9-2f4de48f2759",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def plot_brazilian_coast(plot_where=\"pop-out\"):\n",
+ " \"\"\"\n",
+ " change value of 'plot_where' to:\n",
+ " 'inline' if you would like the plot to show in the notebook\n",
+ " 'pop-out' if you would like the plot to show in a new tab (i.e. seperate window)\n",
+ " \"\"\"\n",
+ "\n",
+ " # below we build the widget\n",
+ " title_bar = pn.Row(\n",
+ " pn.pane.Markdown(\n",
+ " \"## Brazilian Coast\",\n",
+ " styles={\"color\": \"black\"},\n",
+ " sizing_mode=\"fixed\",\n",
+ " margin=(10, 5, 10, 15),\n",
+ " ),\n",
+ " align=\"center\",\n",
+ " )\n",
+ "\n",
+ " # dropdown menu of coasts\n",
+ " options = {\n",
+ " \"Pará\": [\"Princesa\", \"Atalaia\", \"Ajuruteua\"],\n",
+ " \"Maranhão\": [\"São Luís\"],\n",
+ " \"Rio de Janeiro\": [\"Marambaia\"],\n",
+ " \"Santa Catarina\": [\n",
+ " \"Campo Bom\",\n",
+ " \"Laguna\",\n",
+ " \"Enseada de Pinheira\",\n",
+ " \"Praia do Moçambique\",\n",
+ " \"Tijucas\",\n",
+ " \"Balneário Camboriú\",\n",
+ " \"Do Ubatuba\",\n",
+ " \"Barra Velha\",\n",
+ " ],\n",
+ " }\n",
+ " coasts_dropdown = pn.widgets.Select(\n",
+ " name=\"Coast select (grouped by province)\", groups=options, value=\"Campo Bom\"\n",
+ " )\n",
+ "\n",
+ " @pn.depends(coasts_dropdown.param.value)\n",
+ " def plot_coast(name, plot_size=0.04):\n",
+ " beach = gdf[gdf[\"Label\"] == name].copy()\n",
+ " beach = beach.astype({\"Omega [-]\": str})\n",
+ " lat, lon = beach[[\"Latitude\", \"Longitude\"]].values.flatten()\n",
+ " lat, lon = np.float64(lat), np.float64(lon)\n",
+ "\n",
+ " points = gdf.hvplot.points(\n",
+ " geo=True,\n",
+ " tiles=\"ESRI\",\n",
+ " ylabel=\"Latitude [deg]\",\n",
+ " xlabel=\"Longitude [deg]\",\n",
+ " xlim=(lon - plot_size / 2, lon + plot_size / 2),\n",
+ " ylim=(lat - plot_size / 2, lat + plot_size / 2),\n",
+ " tools=[\"tap\"],\n",
+ " hover_cols=[\n",
+ " \"Label\",\n",
+ " \"Province\",\n",
+ " \"Longitude\",\n",
+ " \"Latitude\",\n",
+ " \"Hs [m]\",\n",
+ " \"T [s]\",\n",
+ " \"MTR [m]\",\n",
+ " \"RTR [-]\",\n",
+ " \"D [mm]\",\n",
+ " \"w_s [m/s]\",\n",
+ " \"Beachface slope [degrees]\",\n",
+ " \"Omega [-]\",\n",
+ " ],\n",
+ " c=\"Province\",\n",
+ " cmap=\"Accent\",\n",
+ " line_color=\"black\",\n",
+ " size=300,\n",
+ " )\n",
+ "\n",
+ " plot = (points).opts(width=1200, height=800, tools=[\"wheel_zoom\"])\n",
+ "\n",
+ " return plot\n",
+ "\n",
+ " app = pn.Column(\n",
+ " pn.Row(title_bar, align=\"center\"),\n",
+ " pn.Row(coasts_dropdown, align=\"center\"),\n",
+ " pn.Row(plot_coast, align=\"center\"),\n",
+ " )\n",
+ "\n",
+ " if plot_where == \"inline\":\n",
+ " return app\n",
+ " elif plot_where == \"pop-out\":\n",
+ " app.show()\n",
+ " else:\n",
+ " print(\"please use either inline or pop-out for the plot_where variable\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "98c342cb-22e3-4ba2-b039-4ff723e4d096",
+ "metadata": {},
+ "source": [
+ "### Now plot the coastal data\n",
+ "\n",
+ "Execute the cell below to generate the plot by using the function we defined above. In this plot, coastal systems from 4 different Brazilian provinces are shown. These provinces (from north to south) are Pará, Maranhão, Rio de Janeiro, and Santa Catarina. Please note that altering the slider positions or selecting different options from the dropdown menus may trigger a warning; it can safely be ignored, and possibly silenced by adjusting the logging warning level. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7371762f-02f9-4a04-99fd-587ba0240f17",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "logging.getLogger().setLevel(logging.ERROR)\n",
+ "\n",
+ "plot_brazilian_coast(plot_where=\"pop-out\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7768a848-f236-4713-b639-7e19c35d281b",
+ "metadata": {},
+ "source": [
+ "**Note**: Remember that we are working with an aggregated dataset. Eeach data point should be interpreted as representative of the region around it, and not as specific to that beach.\n",
+ "\n",
+ "You can freely zoom and move around in the generated plot. You can see all of the values from the dataframe when hovering over a data point with the cursor. Some of these values will be needed to answer the questions.\n",
+ "\n",
+ "Using this plot, try to answer the questions below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "34e0c15c-135d-4490-83e8-7c0cb4dd57e2",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q1 = cd.QuestionFactory(questions[\"Q5-1\"]).serve()\n",
+ "q2 = cd.QuestionFactory(questions[\"Q5-2\"]).serve()\n",
+ "q3 = cd.QuestionFactory(questions[\"Q5-3\"]).serve()\n",
+ "q4 = cd.QuestionFactory(questions[\"Q5-4\"]).serve()\n",
+ "\n",
+ "pn.Column(q1, q2, q3, q4)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "eda2d65f-0c9e-44cf-bdd0-d345042e05a5",
+ "metadata": {},
+ "source": [
+ "Have a look at section 4.4.2 from the book, and figure 4.13. Let's try to classify some of the coastal sections using the mean tidal range (MTR) and mean wave height! We plot some of the Brazilian coasts and see how they are classified using the figure. Use the Brazilian coast plot to determine relevant values for the mean tidal range and the mean wave height, and add these values to the data variable below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7cc68af6-7022-4d38-9afa-f00d1cc01cb0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Define points here\n",
+ "data_413 = (\n",
+ " # (\"label\", mean wave height [m], mean tidal range [m], relative tidal range [-]),\n",
+ " (\"Campo Bom\", 1.590, 0.581), # example; you can add more tuples yourself!\n",
+ ")\n",
+ "\n",
+ "# Or uncomment the line below to get all the points\n",
+ "data_413 = zip(gdf.Label, gdf[\"Hs [m]\"], gdf[\"MTR [m]\"], gdf[\"RTR [-]\"])\n",
+ "\n",
+ "df_413 = pd.DataFrame(data_413, columns=(\"Label\", \"Hs [m]\", \"MTR [m]\", \"RTR [-]\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "83c3fa60-4a08-4dd5-9ab2-a5ea20d2dcc1",
+ "metadata": {},
+ "source": [
+ "**Note**: Although you don't have to understand the plot method, we include it here so you can see how these interactive plots are made!\n",
+ "\n",
+ "Again, you can hover over points to get relevant values. Don't forget to have a look at the relative tidal ranges (RTR) for the different coastal systems! The RTR for this specific dataset is actually quite small, but in reality it can be much bigger (>15). For RTR < 3 we have the wave-dominated beaches as described in Section 4.3.3. For RTR > 15 the beaches gradually approach the pure tidal flat situation. The RTR values for the selected Para and Sao Luis beaches hint towards wave-shaped beaches with significant tidal influence and are called tide-dominated beaches in this notebook."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "218faee0-7ea6-4173-ada1-35092545ed94",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "warnings.simplefilter(\"ignore\", category=FutureWarning)\n",
+ "\n",
+ "bokeh.io.output_notebook(INLINE)\n",
+ "hv.extension(\"bokeh\")\n",
+ "\n",
+ "# Load background\n",
+ "fp = pooch.retrieve(\n",
+ " \"https://coclico.blob.core.windows.net/coastal-dynamics/5_coastal_impact_beach_states/5_fig413_bg.jpg\",\n",
+ " known_hash=\"f71b11a7f30fdf49e99379a328f6d018f2181dd906b6b2c4495014336c5e1161\",\n",
+ ")\n",
+ "bg = hv.RGB.load_image(fp, bounds=(0, 0, 2.5, 6)).opts(alpha=0.5)\n",
+ "\n",
+ "# # create the points\n",
+ "points = df_413.hvplot.points(\n",
+ " x=\"Hs [m]\",\n",
+ " y=\"MTR [m]\",\n",
+ " by=\"Label\",\n",
+ " size=100,\n",
+ " cmap=\"Accent\",\n",
+ " line_color=\"black\",\n",
+ " hover_cols=[\"Label\", \"Hs [m]\", \"MTR [m]\", \"RTR [-]\"],\n",
+ ")\n",
+ "\n",
+ "fig413 = (bg * points).opts(\n",
+ " width=700,\n",
+ " height=600,\n",
+ " show_grid=True,\n",
+ " active_tools=[],\n",
+ " toolbar=None,\n",
+ " xlabel=\"mean wave height [m]\",\n",
+ " ylabel=\"mean tidal range [m]\",\n",
+ " xlim=(0, 2.5),\n",
+ " ylim=(0, 6),\n",
+ " show_legend=True,\n",
+ ")\n",
+ "\n",
+ "fig413"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ec0d09f7-b375-4221-98e3-b285ae8dacdf",
+ "metadata": {},
+ "source": [
+ "Using this figure, and the Brazilian coast plot, answer the questions below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5e20d77b-b4d7-4e6d-a349-83a23db8a9cd",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "q5 = cd.QuestionFactory(questions[\"Q5-5\"]).serve()\n",
+ "q6 = cd.QuestionFactory(questions[\"Q5-6\"]).serve()\n",
+ "q7 = cd.QuestionFactory(questions[\"Q5-7\"]).serve()\n",
+ "q8 = cd.QuestionFactory(questions[\"Q5-8\"]).serve()\n",
+ "q9 = cd.QuestionFactory(questions[\"Q5-9\"]).serve()\n",
+ "\n",
+ "pn.Column(q5, q6, q7, q8, q9)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4b6e7a76-be37-4765-86b3-00c15d1e5dde",
+ "metadata": {},
+ "source": [
+ "This is the end of the first part of this notebook. You can continue with the next part on beach states!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "1eafeac4-9de6-4f01-a6fc-d51021245129",
+ "metadata": {},
+ "source": [
+ "## Beach states\n",
+ "For this section, we will focus on the wave-dominated coastal sections (i.e. the coastal sections from the Rio de Janeiro and Santa Catarina coastline). From section 7.3 of the book, you know that a wave-dominated system may be classified as reflective or dissipative, or an intermediate state in between. Note that there is a broad spectrum of intermediate beach states. In this notebook we will not look at this in detail and make some broad generalizations. For instance, we call higher intermediate states “more dissipative” and lower intermediate states “more reflective”. \\\n",
+ "\\\n",
+ "A common classifier used besides the Iribarren number is the dimensionless fall velocity, which is calculated as follows: \\\n",
+ "$$\n",
+ "\\Omega = \\frac{H_b}{w_s T}\n",
+ "$$\n",
+ "where $H_b$ is the wave height at breaking, $T$ is the wave period and $w_s$ is the fall velocity. \\\n",
+ "\\\n",
+ "**Note** that the coastal sections considered as wave-dominated here all have a relative tidal range of lower than 3.\\\n",
+ "\\\n",
+ "Klein et al. (2005) use beach slope and sediment size as a proxy for classifying wave-dominated systems, see also Figure 7.10 in the book. Let's try this for ourselves! We should note that we have looked at regional values for the sediment size, and the beachface slope. Therefore some of the coastal systems from the Brazilian coast plot have equal values for the sediment size and beachface slope. This is also the likely reason that we don't really see any reflective beaches, at least with respect to the data. Note that different coastal sections might still have varying dimensionless fall velocity, even if they are within the same region. Think about why this is the case.\n",
+ "\n",
+ "The regions are displayed in the legend of the plot below, so you can see which coastal systems belong to which regions. Alternatively, a table is provided below.\n",
+ "\n",
+ "| Region (in Santa Catarina province) | Coastal section | D [mm] | Beachface slope [degrees] |\n",
+ "| :---------------------------------- | :------------------------------- | :----- | :------------------------ |\n",
+ "| 1 | Barra Velha,
Do Ubatuba | 0\\.30 | 5\\.0 |\n",
+ "| 2 | Balnario Camboriu,
Tijucas | 0\\.32 | 5\\.0 |\n",
+ "| 3 | Praia do Macambique | 0\\.30 | 4\\.1 |\n",
+ "| 4 | Enseada de Pinheira,
Laguna | 0\\.19 | 3\\.0 |\n",
+ "| 5 | Campo Bom | 0\\.21 | 1\\.8 |"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d5433936-ddcc-4a67-ac75-fb46982b2d52",
+ "metadata": {},
+ "source": [
+ "Finish the code below with some of the coastal sections to show where they would lie in figure 7.10."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1a1d96d8-7e73-45f5-82e9-f9aa3ccd2b4c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Define points here\n",
+ "data_710 = (\n",
+ " # (\"label\", slope [degrees], mean grain size [mm], Omega [-]),\n",
+ " (\"Campo Bom\", 2.987, 0.21, 4.385), # example; you can add more tuples yourself!\n",
+ ")\n",
+ "\n",
+ "# Or uncomment the lines below to get all the points\n",
+ "data_710 = zip(\n",
+ " gdf[gdf.Province == \"Santa Catarina\"].Label,\n",
+ " gdf[gdf.Province == \"Santa Catarina\"][\"Beachface slope [degrees]\"],\n",
+ " gdf[gdf.Province == \"Santa Catarina\"][\"D [mm]\"],\n",
+ " gdf[gdf.Province == \"Santa Catarina\"][\"Omega [-]\"],\n",
+ ")\n",
+ "data_710 = list(data_710)\n",
+ "data_710.append(\n",
+ " list(\n",
+ " zip(\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"].Label,\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"][\"Beachface slope [degrees]\"],\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"][\"D [mm]\"],\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"][\"Omega [-]\"],\n",
+ " )\n",
+ " )[0]\n",
+ ")\n",
+ "\n",
+ "df_710 = pd.DataFrame(\n",
+ " data=data_710, columns=(\"Label\", \"Beachface slope [degrees]\", \"D [mm]\", \"Omega [-]\")\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "77000ecd-d7d9-435c-b519-f59571ad3f67",
+ "metadata": {},
+ "source": [
+ "**Note**: Although you don't have to understand the plot method, we include it here so you can see how these interactive plots are made!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5ee9ada3-b3e6-45f9-b0a9-316d626ae603",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "warnings.simplefilter(\"ignore\", category=UserWarning)\n",
+ "\n",
+ "r = 1\n",
+ "ps = hv.Points([])\n",
+ "\n",
+ "for slope, D in [(5, 0.3), (5, 0.32), (4.1, 0.3), (3, 0.19), (1.8, 0.21), (7.4, 0.6)]:\n",
+ " df = df_710[df_710[\"Beachface slope [degrees]\"] == slope][df_710[\"D [mm]\"] == D]\n",
+ "\n",
+ " # plot the points\n",
+ " if r == 6:\n",
+ " point = (\n",
+ " df.hvplot.points(\n",
+ " x=\"Beachface slope [degrees]\",\n",
+ " y=\"D [mm]\",\n",
+ " size=100,\n",
+ " c=\"Label\",\n",
+ " cmap=\"Accent\",\n",
+ " hover_cols=[\n",
+ " \"Label\",\n",
+ " \"Beachface slope [degrees]\",\n",
+ " \"D [mm]\",\n",
+ " \"Omega [-]\",\n",
+ " ],\n",
+ " line_color=\"black\",\n",
+ " )\n",
+ " .opts(xlabel=\"Slope [degrees]\", ylabel=\"Mean grain size [mm]\")\n",
+ " .relabel(\"Rio de Janeiro, Marambaia\")\n",
+ " )\n",
+ " else:\n",
+ " point = df.hvplot.points(\n",
+ " x=\"Beachface slope [degrees]\",\n",
+ " y=\"D [mm]\",\n",
+ " size=100,\n",
+ " cmap=\"Accent\",\n",
+ " hover_cols=[\"Label\", \"Beachface slope [degrees]\", \"D [mm]\", \"Omega [-]\"],\n",
+ " line_color=\"black\",\n",
+ " label=f\"Santa Catarina, region {r}\",\n",
+ " ).opts(xlabel=\"Slope [degrees]\", ylabel=\"Mean grain size [mm]\")\n",
+ "\n",
+ " # add points to ps variable\n",
+ " ps *= point\n",
+ "\n",
+ " # used for labelling of the regions\n",
+ " r += 1\n",
+ "\n",
+ "# plot horizontal and vertical lines\n",
+ "hlines = hv.HLine(0.25).opts(color=\"lightgrey\") * hv.HLine(0.5).opts(color=\"lightgrey\")\n",
+ "vlines = (\n",
+ " hv.VLine(3.5).opts(color=\"lightgrey\") * hv.VLine(8.5).opts(color=\"lightgrey\")\n",
+ ").opts(border_line_color=\"lightgrey\")\n",
+ "\n",
+ "# plot labels\n",
+ "classify_labels = (\n",
+ " hv.Text(1.75, 0.95, \"dissipative\", fontsize=10)\n",
+ " * hv.Text(6, 0.95, \"intermediate\", fontsize=10)\n",
+ " * hv.Text(13, 0.95, \"reflective\", fontsize=10)\n",
+ ")\n",
+ "\n",
+ "grain_labels = (\n",
+ " hv.Text(15.8, 0.75, \"coarse sand\", fontsize=10, halign=\"right\")\n",
+ " * hv.Text(15.8, 0.375, \"medium sand\", fontsize=10, halign=\"right\")\n",
+ " * hv.Text(15.8, 0.125, \"fine sand\", fontsize=10, halign=\"right\")\n",
+ ")\n",
+ "\n",
+ "\n",
+ "fig710 = (ps * hlines * vlines * classify_labels * grain_labels).opts(\n",
+ " ylim=(0, 1), xlim=(0, 16), width=1200, height=600, active_tools=[], toolbar=None\n",
+ ")\n",
+ "\n",
+ "fig710"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "526b7bb5-8b8b-4e40-8aff-492baa728635",
+ "metadata": {},
+ "source": [
+ "Using the plot above, as well as the Brazilian coast plot, try to answer the questions below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4593bd94-d241-47df-8cc1-c8886cea4cb8",
+ "metadata": {
+ "jp-MarkdownHeadingCollapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "q10 = cd.QuestionFactory(questions[\"Q5-10\"]).serve()\n",
+ "q11 = cd.QuestionFactory(questions[\"Q5-11\"]).serve()\n",
+ "q12 = cd.QuestionFactory(questions[\"Q5-12\"]).serve()\n",
+ "q13 = cd.QuestionFactory(questions[\"Q5-13\"]).serve()\n",
+ "q14 = cd.QuestionFactory(questions[\"Q5-14\"]).serve()\n",
+ "q15 = cd.QuestionFactory(questions[\"Q5-15\"]).serve()\n",
+ "q16 = cd.QuestionFactory(questions[\"Q5-16\"]).serve()\n",
+ "q17 = cd.QuestionFactory(questions[\"Q5-17\"]).serve()\n",
+ "q18 = cd.QuestionFactory(questions[\"Q5-18\"]).serve()\n",
+ "q19 = cd.QuestionFactory(questions[\"Q5-19\"]).serve()\n",
+ "q20 = cd.QuestionFactory(questions[\"Q5-20\"]).serve()\n",
+ "q21 = cd.QuestionFactory(questions[\"Q5-21\"]).serve()\n",
+ "\n",
+ "pn.Column(q10, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "514a3b78-47da-4ccb-86b8-957ad3d5b702",
+ "metadata": {},
+ "source": [
+ "This is the end of the notebook for week 5."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6cfe7d0a-1643-45cb-ae97-ead85e8d180e",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python [conda env:coastal] *",
+ "language": "python",
+ "name": "conda-env-coastal-py"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.7"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/book/notebooks/initialize/5_cross_shore_transport.ipynb b/book/notebooks/initialize/5_coastal_impact_beach_states.ipynb
similarity index 100%
rename from book/notebooks/initialize/5_cross_shore_transport.ipynb
rename to book/notebooks/initialize/5_coastal_impact_beach_states.ipynb
diff --git a/book/notebooks/initialize/6_cross_shore_transport.ipynb b/book/notebooks/initialize/6_cross_shore_transport.ipynb
new file mode 100644
index 0000000..bfb52ea
--- /dev/null
+++ b/book/notebooks/initialize/6_cross_shore_transport.ipynb
@@ -0,0 +1,296 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "297694e4-4215-4f65-aecc-afd612b34310",
+ "metadata": {},
+ "source": [
+ "### Import Packages\n",
+ "Start with some generally useful packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b52b50dc-b572-4bc7-9168-424f1ef5b94b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from random import shuffle, uniform\n",
+ "\n",
+ "import IPython\n",
+ "import ipywidgets as widgets\n",
+ "import matplotlib.animation as animation\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "from IPython.display import HTML, display\n",
+ "from ipywidgets import interact\n",
+ "from matplotlib.animation import FuncAnimation\n",
+ "from matplotlib.ticker import MultipleLocator\n",
+ "\n",
+ "import pandas as pd\n",
+ "import hvplot.pandas\n",
+ "import panel as pn\n",
+ "import holoviews as hv"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f5a9dc63-e0ea-4ed4-9c5a-8e1b64a5b784",
+ "metadata": {},
+ "source": [
+ "Import other packages in order to let the different question classes run."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8b27eeb8-285e-451f-91cf-0d5ce6bef1fc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pathlib\n",
+ "import sys\n",
+ "\n",
+ "from PIL import Image\n",
+ "from coastal_dynamics.hidden import *\n",
+ "\n",
+ "# make functions for src folder importable\n",
+ "cwd = pathlib.Path().resolve()\n",
+ "proj_dir = cwd.parent # this is the notebooks folder\n",
+ "sys.path.append(str(proj_dir / \"src\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "494b923e-ecee-4fb9-a3fe-b9ba9c4ff200",
+ "metadata": {},
+ "source": [
+ "And import the question types."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b5e7a1e4-1061-4998-8bc1-11d93ed29b76",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from coastal_dynamics.questions.multiple_choice import MultipleChoiceQuestion\n",
+ "from coastal_dynamics.questions.multiple_selection import MultipleSelectionQuestion\n",
+ "from coastal_dynamics.questions.numeric import NumericQuestion\n",
+ "from coastal_dynamics.questions.text import TextQuestion"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "140c4563-0cc2-439f-895f-61e3e6d576b6",
+ "metadata": {},
+ "source": [
+ "Finally import the imports for the widgets."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8ee00f0f-577f-41f3-a031-dfb21d68c27e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from ipywidgets import interact, interactive, fixed, interact_manual\n",
+ "from ipywidgets import interact\n",
+ "import ipywidgets as ipw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ddcc66a5-4b10-4d6f-a225-00d88c854897",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"Packages succesfully loaded\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bf87ab4c-e627-4e7e-b2c9-53e264fbc98d",
+ "metadata": {},
+ "source": [
+ "### Directories\n",
+ "Set the right directories such that the figures work correctly."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5893e3ca-edfe-48f4-9313-74dbdfe55084",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "DATA_DIR = proj_dir / \"data\"\n",
+ "FIG_DIR = proj_dir / \"coastalcodebook\" / \"assignments\" / \"figures\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "93f25bc4-d826-44e5-a965-fe63499bd321",
+ "metadata": {},
+ "source": [
+ "### Initialize\n",
+ "Initialize such that the panel works."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "f3a72f57-9ca1-42b6-9bdd-3cbdeb45ff15",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pn.extension()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "94ce6db2-e8b4-445c-ba93-069798a97a80",
+ "metadata": {},
+ "source": [
+ "### Question types\n",
+ "Below the functions for producing the different question types are defined."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2ebca2ef-1b8d-4956-b4d6-c305b9db4248",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def MC(question_data):\n",
+ " Q = MultipleChoiceQuestion(\n",
+ " question_name=question_data[\"name\"],\n",
+ " question_text=question_data[\"question\"],\n",
+ " question_options=question_data[\"options\"],\n",
+ " question_answer=question_data[\"answer\"],\n",
+ " question_feedback=question_data[\"feedback\"]\n",
+ " )\n",
+ "\n",
+ " Q.create_widgets()\n",
+ " return Q.serve()\n",
+ "\n",
+ "def MS(question_data):\n",
+ " Q = MultipleSelectionQuestion(\n",
+ " question_name=question_data[\"name\"],\n",
+ " question_text=question_data[\"question\"],\n",
+ " question_options=question_data[\"options\"],\n",
+ " question_answers=question_data[\"answers\"],\n",
+ " question_feedback=question_data[\"feedback\"]\n",
+ " )\n",
+ " Q.create_widgets()\n",
+ " return Q.serve()\n",
+ "\n",
+ "def num(question_data):\n",
+ " Q = NumericQuestion(\n",
+ " question_name=question_data[\"name\"],\n",
+ " question_text=question_data[\"question\"],\n",
+ " question_answer=question_data[\"answer\"],\n",
+ " question_feedback=question_data[\"feedback\"],\n",
+ " precision=question_data[\"precision\"]\n",
+ " )\n",
+ "\n",
+ " Q.create_widgets()\n",
+ " return Q.serve()\n",
+ "\n",
+ "def text(question_data):\n",
+ " Q = TextQuestion(\n",
+ " question_name=question_data[\"name\"],\n",
+ " question_text=question_data[\"question\"],\n",
+ " question_answer=question_data[\"answer\"],\n",
+ " question_feedback=question_data[\"feedback\"],\n",
+ " )\n",
+ "\n",
+ " Q.create_widgets()\n",
+ " return Q.serve()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d5a7bcbf-1cc2-4760-91c5-537ec76bfe3d",
+ "metadata": {},
+ "source": [
+ "### Question data & functions\n",
+ "Below the question data is defined (seperated by section). The questions where students are asked to reproduce plots contain functions, which are also defined below. The question data and functions are defined in the same order as they are asked in the notebook."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5c550559-452a-4d20-bd94-005fa0572047",
+ "metadata": {},
+ "source": [
+ "#### Section 1\n",
+ "Question data for questions in section 1."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2de38515-e7fc-4d75-97c3-b97fba421e85",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# To be moved to initializer"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "38056b14-eabc-4a13-bd11-84e9bc5bc9f2",
+ "metadata": {},
+ "source": [
+ "#### Section 2\n",
+ "Question data for questions in section 2."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6ccfe4d0-ecf6-4151-8aa8-48fdeded821e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# To be moved to initializer"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "e302a97a-aa10-4150-8782-a3e336ecde95",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(\"Questions succesfully loaded\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.7"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/notebooks/5_coastal_impact_beach_states.ipynb b/notebooks/5_coastal_impact_beach_states.ipynb
index 6c8d14f..425dd96 100644
--- a/notebooks/5_coastal_impact_beach_states.ipynb
+++ b/notebooks/5_coastal_impact_beach_states.ipynb
@@ -1,5 +1,13 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "84d7581d-d784-4863-8b98-8091aba15a86",
+ "metadata": {},
+ "source": [
+ "# Coastal Impact Beach States"
+ ]
+ },
{
"cell_type": "markdown",
"id": "968bd444-a7c0-44f6-8648-60b84b483abf",
@@ -20,27 +28,25 @@
"import pathlib\n",
"import warnings\n",
"\n",
+ "import bokeh.io\n",
"import colorcet as cc\n",
"import geopandas as gpd\n",
"import holoviews as hv\n",
"import hvplot.pandas # noqa: API import\n",
"import ipyleaflet\n",
- "import numpy as np\n",
- "import pandas as pd\n",
- "import panel as pn\n",
- "\n",
"import IPython\n",
"import ipywidgets as widgets\n",
"import matplotlib.pyplot as plt\n",
- "from IPython.display import HTML, display\n",
- "\n",
- "from bokeh.models import PanTool, WheelZoomTool, HoverTool\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import panel as pn\n",
+ "from bokeh.models import HoverTool, PanTool, WheelZoomTool\n",
"from bokeh.resources import INLINE\n",
- "import bokeh.io\n",
+ "from IPython.display import HTML, display\n",
"\n",
"import coastal_dynamics as cd\n",
"\n",
- "# Silence DeprecationWarning # Future TODO: in spring 2024 rm this silence and check status \n",
+ "# Silence DeprecationWarning # Future TODO: in spring 2024 rm this silence and check status\n",
"with warnings.catch_warnings():\n",
" warnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n",
" import dask.dataframe as dd\n",
@@ -128,10 +134,29 @@
"source": [
"import pooch\n",
"\n",
- "fp = pooch.retrieve(\"https://coclico.blob.core.windows.net/coastal-dynamics/5_coastal_impact_beach_states/5_data.gpkg\", known_hash=\"661ddc9ad6a396dd6fe9a9cf2126a32b1134fef92075fa19f5ee1ee445125934\")\n",
+ "fp = pooch.retrieve(\n",
+ " \"https://coclico.blob.core.windows.net/coastal-dynamics/5_coastal_impact_beach_states/5_data.gpkg\",\n",
+ " known_hash=\"661ddc9ad6a396dd6fe9a9cf2126a32b1134fef92075fa19f5ee1ee445125934\",\n",
+ ")\n",
"\n",
"# We load this file as a GeoDataFrame, which comes with a column containing the geometry of each entry. For this dataset, these are points (longitude, latitude)\n",
"gdf = gpd.read_file(fp)\n",
+ "\n",
+ "\n",
+ "def convert_to_numeric(value):\n",
+ " if pd.isnull(value):\n",
+ " return np.nan # Convert None to NaN\n",
+ " if value.startswith(\">\"):\n",
+ " epsilon = 0.1 # Define how much greater\n",
+ " return float(value[1:])\n",
+ " elif value.startswith(\"~\"):\n",
+ " return float(value[1:])\n",
+ " else:\n",
+ " return float(value)\n",
+ "\n",
+ "\n",
+ "gdf[\"Omega [-]\"] = gdf[\"Omega [-]\"].apply(convert_to_numeric)\n",
+ "\n",
"gdf.head()"
]
},
@@ -169,76 +194,95 @@
"metadata": {},
"outputs": [],
"source": [
- "def plot_brazilian_coast(plot_where='pop-out'):\n",
+ "def plot_brazilian_coast(plot_where=\"pop-out\"):\n",
" \"\"\"\n",
" change value of 'plot_where' to:\n",
" 'inline' if you would like the plot to show in the notebook\n",
" 'pop-out' if you would like the plot to show in a new tab (i.e. seperate window)\n",
" \"\"\"\n",
- " \n",
+ "\n",
" # below we build the widget\n",
" title_bar = pn.Row(\n",
- " pn.pane.Markdown(\"## Brazilian Coast\",\n",
- " styles={\"color\": \"black\"},\n",
- " sizing_mode=\"fixed\",\n",
- " margin=(10,5,10,15),\n",
+ " pn.pane.Markdown(\n",
+ " \"## Brazilian Coast\",\n",
+ " styles={\"color\": \"black\"},\n",
+ " sizing_mode=\"fixed\",\n",
+ " margin=(10, 5, 10, 15),\n",
" ),\n",
- " align='center',\n",
+ " align=\"center\",\n",
" )\n",
"\n",
" # dropdown menu of coasts\n",
- " options = {\"Pará\":[\"Princesa\", \"Atalaia\", \"Ajuruteua\"],\n",
- " \"Maranhão\":[\"São Luís\"],\n",
- " \"Rio de Janeiro\":[\"Marambaia\"],\n",
- " \"Santa Catarina\":[\"Campo Bom\", \"Laguna\", \"Enseada de Pinheira\", \"Praia do Moçambique\",\n",
- " \"Tijucas\", \"Balneário Camboriú\", \"Do Ubatuba\", \"Barra Velha\"],\n",
- " }\n",
+ " options = {\n",
+ " \"Pará\": [\"Princesa\", \"Atalaia\", \"Ajuruteua\"],\n",
+ " \"Maranhão\": [\"São Luís\"],\n",
+ " \"Rio de Janeiro\": [\"Marambaia\"],\n",
+ " \"Santa Catarina\": [\n",
+ " \"Campo Bom\",\n",
+ " \"Laguna\",\n",
+ " \"Enseada de Pinheira\",\n",
+ " \"Praia do Moçambique\",\n",
+ " \"Tijucas\",\n",
+ " \"Balneário Camboriú\",\n",
+ " \"Do Ubatuba\",\n",
+ " \"Barra Velha\",\n",
+ " ],\n",
+ " }\n",
" coasts_dropdown = pn.widgets.Select(\n",
- " name=\"Coast select (grouped by province)\", groups=options, value=\"Campo Bom\")\n",
+ " name=\"Coast select (grouped by province)\", groups=options, value=\"Campo Bom\"\n",
+ " )\n",
"\n",
" @pn.depends(coasts_dropdown.param.value)\n",
" def plot_coast(name, plot_size=0.04):\n",
- " beach = gdf[gdf['Label']==name].copy()\n",
- " lat, lon = beach[['Latitude', 'Longitude']].values.flatten()\n",
+ " beach = gdf[gdf[\"Label\"] == name].copy()\n",
+ " beach = beach.astype({\"Omega [-]\": str})\n",
+ " lat, lon = beach[[\"Latitude\", \"Longitude\"]].values.flatten()\n",
" lat, lon = np.float64(lat), np.float64(lon)\n",
- " \n",
+ "\n",
" points = gdf.hvplot.points(\n",
" geo=True,\n",
- " tiles='ESRI',\n",
- " ylabel='Latitude [deg]',\n",
- " xlabel='Longitude [deg]',\n",
- " xlim=(lon-plot_size/2, lon+plot_size/2),\n",
- " ylim=(lat-plot_size/2, lat+plot_size/2),\n",
- " tools=['tap'],\n",
- " hover_cols=['Label', 'Province', \n",
- " 'Longitude', 'Latitude', \n",
- " 'Hs [m]', 'T [s]', 'MTR [m]', 'RTR [-]',\n",
- " 'D [mm]', 'w_s [m/s]',\n",
- " 'Beachface slope [degrees]', 'Omega [-]'],\n",
- " c='Province',\n",
- " cmap='Accent',\n",
- " line_color='black',\n",
+ " tiles=\"ESRI\",\n",
+ " ylabel=\"Latitude [deg]\",\n",
+ " xlabel=\"Longitude [deg]\",\n",
+ " xlim=(lon - plot_size / 2, lon + plot_size / 2),\n",
+ " ylim=(lat - plot_size / 2, lat + plot_size / 2),\n",
+ " tools=[\"tap\"],\n",
+ " hover_cols=[\n",
+ " \"Label\",\n",
+ " \"Province\",\n",
+ " \"Longitude\",\n",
+ " \"Latitude\",\n",
+ " \"Hs [m]\",\n",
+ " \"T [s]\",\n",
+ " \"MTR [m]\",\n",
+ " \"RTR [-]\",\n",
+ " \"D [mm]\",\n",
+ " \"w_s [m/s]\",\n",
+ " \"Beachface slope [degrees]\",\n",
+ " \"Omega [-]\",\n",
+ " ],\n",
+ " c=\"Province\",\n",
+ " cmap=\"Accent\",\n",
+ " line_color=\"black\",\n",
" size=300,\n",
- " )\n",
+ " )\n",
"\n",
- " plot = (points).opts(\n",
- " width=1200,\n",
- " height=800,\n",
- " tools=['wheel_zoom']\n",
- " )\n",
+ " plot = (points).opts(width=1200, height=800, tools=[\"wheel_zoom\"])\n",
"\n",
" return plot\n",
"\n",
- " app = pn.Column(pn.Row(title_bar, align=\"center\"),\n",
- " pn.Row(coasts_dropdown, align=\"center\"),\n",
- " pn.Row(plot_coast, align=\"center\"))\n",
- " \n",
+ " app = pn.Column(\n",
+ " pn.Row(title_bar, align=\"center\"),\n",
+ " pn.Row(coasts_dropdown, align=\"center\"),\n",
+ " pn.Row(plot_coast, align=\"center\"),\n",
+ " )\n",
+ "\n",
" if plot_where == \"inline\":\n",
" return app\n",
" elif plot_where == \"pop-out\":\n",
" app.show()\n",
" else:\n",
- " print(\"please use either inline or pop-out for the plot_where variable\")"
+ " print(\"please use either inline or pop-out for the plot_where variable\")\n"
]
},
{
@@ -308,13 +352,13 @@
"# Define points here\n",
"data_413 = (\n",
" # (\"label\", mean wave height [m], mean tidal range [m], relative tidal range [-]),\n",
- " (\"Campo Bom\", 1.590, 0.581), # example; you can add more tuples yourself!\n",
+ " (\"Campo Bom\", 1.590, 0.581), # example; you can add more tuples yourself!\n",
")\n",
"\n",
"# Or uncomment the line below to get all the points\n",
- "data_413 = zip(gdf.Label, gdf['Hs [m]'], gdf['MTR [m]'], gdf['RTR [-]'])\n",
+ "data_413 = zip(gdf.Label, gdf[\"Hs [m]\"], gdf[\"MTR [m]\"], gdf[\"RTR [-]\"])\n",
"\n",
- "df_413 = pd.DataFrame(data_413, columns=('Label', 'Hs [m]', 'MTR [m]', 'RTR [-]'))"
+ "df_413 = pd.DataFrame(data_413, columns=(\"Label\", \"Hs [m]\", \"MTR [m]\", \"RTR [-]\"))"
]
},
{
@@ -334,21 +378,42 @@
"metadata": {},
"outputs": [],
"source": [
+ "warnings.simplefilter(\"ignore\", category=FutureWarning)\n",
+ "\n",
"bokeh.io.output_notebook(INLINE)\n",
- "hv.extension('bokeh')\n",
- " \n",
+ "hv.extension(\"bokeh\")\n",
+ "\n",
"# Load background\n",
- "fp = pooch.retrieve(\"https://coclico.blob.core.windows.net/coastal-dynamics/5_coastal_impact_beach_states/5_fig413_bg.jpg\", known_hash=\"f71b11a7f30fdf49e99379a328f6d018f2181dd906b6b2c4495014336c5e1161\")\n",
- "bg = hv.RGB.load_image(fp, bounds=(0,0,2.5,6)).opts(alpha=0.5)\n",
+ "fp = pooch.retrieve(\n",
+ " \"https://coclico.blob.core.windows.net/coastal-dynamics/5_coastal_impact_beach_states/5_fig413_bg.jpg\",\n",
+ " known_hash=\"f71b11a7f30fdf49e99379a328f6d018f2181dd906b6b2c4495014336c5e1161\",\n",
+ ")\n",
+ "bg = hv.RGB.load_image(fp, bounds=(0, 0, 2.5, 6)).opts(alpha=0.5)\n",
"\n",
"# # create the points\n",
- "points = df_413.hvplot.points(x='Hs [m]', y='MTR [m]', by='Label', size=100,\n",
- " cmap='Accent',\n",
- " line_color='black',\n",
- " hover_cols=['Label', 'Hs [m]', 'MTR [m]', 'RTR [-]'])\n",
+ "points = df_413.hvplot.points(\n",
+ " x=\"Hs [m]\",\n",
+ " y=\"MTR [m]\",\n",
+ " by=\"Label\",\n",
+ " size=100,\n",
+ " cmap=\"Accent\",\n",
+ " line_color=\"black\",\n",
+ " hover_cols=[\"Label\", \"Hs [m]\", \"MTR [m]\", \"RTR [-]\"],\n",
+ ")\n",
+ "\n",
+ "fig413 = (bg * points).opts(\n",
+ " width=700,\n",
+ " height=600,\n",
+ " show_grid=True,\n",
+ " active_tools=[],\n",
+ " toolbar=None,\n",
+ " xlabel=\"mean wave height [m]\",\n",
+ " ylabel=\"mean tidal range [m]\",\n",
+ " xlim=(0, 2.5),\n",
+ " ylim=(0, 6),\n",
+ " show_legend=True,\n",
+ ")\n",
"\n",
- "fig413 = (bg*points).opts(width=700, height=600, show_grid=True, active_tools=[], toolbar=None, xlabel='mean wave height [m]', ylabel='mean tidal range [m]', xlim=(0,2.5), ylim=(0,6), show_legend=True)\n",
- " \n",
"fig413"
]
},
@@ -431,15 +496,31 @@
"# Define points here\n",
"data_710 = (\n",
" # (\"label\", slope [degrees], mean grain size [mm], Omega [-]),\n",
- " (\"Campo Bom\", 2.987, 0.21, 4.385), # example; you can add more tuples yourself!\n",
+ " (\"Campo Bom\", 2.987, 0.21, 4.385), # example; you can add more tuples yourself!\n",
")\n",
"\n",
"# Or uncomment the lines below to get all the points\n",
- "data_710 = zip(gdf[gdf.Province=='Santa Catarina'].Label, gdf[gdf.Province=='Santa Catarina']['Beachface slope [degrees]'], gdf[gdf.Province=='Santa Catarina']['D [mm]'], gdf[gdf.Province=='Santa Catarina']['Omega [-]'])\n",
+ "data_710 = zip(\n",
+ " gdf[gdf.Province == \"Santa Catarina\"].Label,\n",
+ " gdf[gdf.Province == \"Santa Catarina\"][\"Beachface slope [degrees]\"],\n",
+ " gdf[gdf.Province == \"Santa Catarina\"][\"D [mm]\"],\n",
+ " gdf[gdf.Province == \"Santa Catarina\"][\"Omega [-]\"],\n",
+ ")\n",
"data_710 = list(data_710)\n",
- "data_710.append(list(zip(gdf[gdf.Province=='Rio de Janeiro'].Label, gdf[gdf.Province=='Rio de Janeiro']['Beachface slope [degrees]'], gdf[gdf.Province=='Rio de Janeiro']['D [mm]'], gdf[gdf.Province=='Rio de Janeiro']['Omega [-]']))[0])\n",
+ "data_710.append(\n",
+ " list(\n",
+ " zip(\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"].Label,\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"][\"Beachface slope [degrees]\"],\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"][\"D [mm]\"],\n",
+ " gdf[gdf.Province == \"Rio de Janeiro\"][\"Omega [-]\"],\n",
+ " )\n",
+ " )[0]\n",
+ ")\n",
"\n",
- "df_710 = pd.DataFrame(data=data_710, columns=('Label', 'Beachface slope [degrees]', 'D [mm]', 'Omega [-]'))"
+ "df_710 = pd.DataFrame(\n",
+ " data=data_710, columns=(\"Label\", \"Beachface slope [degrees]\", \"D [mm]\", \"Omega [-]\")\n",
+ ")"
]
},
{
@@ -457,41 +538,74 @@
"metadata": {},
"outputs": [],
"source": [
- "r = 1\n",
+ "warnings.simplefilter(\"ignore\", category=UserWarning)\n",
+ "\n",
+ "r = 1\n",
"ps = hv.Points([])\n",
"\n",
"for slope, D in [(5, 0.3), (5, 0.32), (4.1, 0.3), (3, 0.19), (1.8, 0.21), (7.4, 0.6)]:\n",
- " df = df_710[df_710['Beachface slope [degrees]']==slope][df_710['D [mm]']==D]\n",
+ " df = df_710[df_710[\"Beachface slope [degrees]\"] == slope][df_710[\"D [mm]\"] == D]\n",
"\n",
" # plot the points\n",
" if r == 6:\n",
- " point = df.hvplot.points(x='Beachface slope [degrees]', y='D [mm]', size=100, c='Label', cmap='Accent', hover_cols=['Label', 'Beachface slope [degrees]', 'D [mm]', 'Omega [-]'],\n",
- " line_color='black',).opts(xlabel='Slope [degrees]', ylabel='Mean grain size [mm]').relabel('Rio de Janeiro, Marambaia')\n",
+ " point = (\n",
+ " df.hvplot.points(\n",
+ " x=\"Beachface slope [degrees]\",\n",
+ " y=\"D [mm]\",\n",
+ " size=100,\n",
+ " c=\"Label\",\n",
+ " cmap=\"Accent\",\n",
+ " hover_cols=[\n",
+ " \"Label\",\n",
+ " \"Beachface slope [degrees]\",\n",
+ " \"D [mm]\",\n",
+ " \"Omega [-]\",\n",
+ " ],\n",
+ " line_color=\"black\",\n",
+ " )\n",
+ " .opts(xlabel=\"Slope [degrees]\", ylabel=\"Mean grain size [mm]\")\n",
+ " .relabel(\"Rio de Janeiro, Marambaia\")\n",
+ " )\n",
" else:\n",
- " point = df.hvplot.points(x='Beachface slope [degrees]', y='D [mm]', size=100, cmap='Accent', hover_cols=['Label', 'Beachface slope [degrees]', 'D [mm]', 'Omega [-]'],\n",
- " line_color='black', label=f'Santa Catarina, region {r}').opts(xlabel='Slope [degrees]', ylabel='Mean grain size [mm]')\n",
+ " point = df.hvplot.points(\n",
+ " x=\"Beachface slope [degrees]\",\n",
+ " y=\"D [mm]\",\n",
+ " size=100,\n",
+ " cmap=\"Accent\",\n",
+ " hover_cols=[\"Label\", \"Beachface slope [degrees]\", \"D [mm]\", \"Omega [-]\"],\n",
+ " line_color=\"black\",\n",
+ " label=f\"Santa Catarina, region {r}\",\n",
+ " ).opts(xlabel=\"Slope [degrees]\", ylabel=\"Mean grain size [mm]\")\n",
"\n",
" # add points to ps variable\n",
" ps *= point\n",
"\n",
" # used for labelling of the regions\n",
- " r+=1\n",
+ " r += 1\n",
"\n",
"# plot horizontal and vertical lines\n",
- "hlines = (hv.HLine(0.25).opts(color='lightgrey') * hv.HLine(0.5).opts(color='lightgrey'))\n",
- "vlines = (hv.VLine(3.5).opts(color='lightgrey') * hv.VLine(8.5).opts(color='lightgrey')).opts(border_line_color='lightgrey')\n",
+ "hlines = hv.HLine(0.25).opts(color=\"lightgrey\") * hv.HLine(0.5).opts(color=\"lightgrey\")\n",
+ "vlines = (\n",
+ " hv.VLine(3.5).opts(color=\"lightgrey\") * hv.VLine(8.5).opts(color=\"lightgrey\")\n",
+ ").opts(border_line_color=\"lightgrey\")\n",
"\n",
"# plot labels\n",
- "classify_labels = hv.Text(1.75, 0.95, \"dissipative\", fontsize=10) * \\\n",
- " hv.Text(6, 0.95, \"intermediate\", fontsize=10) * \\\n",
- " hv.Text(13, 0.95, \"reflective\", fontsize=10)\n",
+ "classify_labels = (\n",
+ " hv.Text(1.75, 0.95, \"dissipative\", fontsize=10)\n",
+ " * hv.Text(6, 0.95, \"intermediate\", fontsize=10)\n",
+ " * hv.Text(13, 0.95, \"reflective\", fontsize=10)\n",
+ ")\n",
"\n",
- "grain_labels = hv.Text(15.8, 0.75, \"coarse sand\", fontsize=10, halign='right') * \\\n",
- " hv.Text(15.8, 0.375, \"medium sand\", fontsize=10, halign='right') * \\\n",
- " hv.Text(15.8, 0.125, \"fine sand\", fontsize=10, halign='right')\n",
+ "grain_labels = (\n",
+ " hv.Text(15.8, 0.75, \"coarse sand\", fontsize=10, halign=\"right\")\n",
+ " * hv.Text(15.8, 0.375, \"medium sand\", fontsize=10, halign=\"right\")\n",
+ " * hv.Text(15.8, 0.125, \"fine sand\", fontsize=10, halign=\"right\")\n",
+ ")\n",
"\n",
"\n",
- "fig710 = (ps * hlines * vlines * classify_labels * grain_labels).opts(ylim=(0, 1), xlim=(0, 16), width=1200, height=600, active_tools=[], toolbar=None)\n",
+ "fig710 = (ps * hlines * vlines * classify_labels * grain_labels).opts(\n",
+ " ylim=(0, 1), xlim=(0, 16), width=1200, height=600, active_tools=[], toolbar=None\n",
+ ")\n",
"\n",
"fig710"
]
@@ -536,6 +650,14 @@
"source": [
"This is the end of the notebook for week 5."
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6cfe7d0a-1643-45cb-ae97-ead85e8d180e",
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
@@ -554,7 +676,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.8"
+ "version": "3.11.7"
}
},
"nbformat": 4,