{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 6B\n", "\n", "This part of exercise deals with post-processing of results from structural elements of Plaxis FE geotechnical calculation. The output is bending moment in plate elements and we will filter the results and plot each Construction Stage with its values into one figure per Stage for each plate. \n", "\n", "Note that for the purpose of this exercise, we are only extracting the bending moment data for illustration; the idea could be extended to any other results anyone would like to extract. Also, for simplicity, we are dealing with txt data files from Plaxis output; the process of extracting the data into the txt files (which takes quite some time to do) can be skipped by directly connecting Plaxis to Python (see https://www.plaxis.com/support/python-scripts/scripting-reference-and-how-to-use-it/)\n", "\n", "The model is shown in the first figure below. It has two plate elements of the retaining wall, namely \"Plate1\" and \"Plate2\" which extend vertically from the ground level to the toe level.\n", "Note that each plate element consists of multiple smaller plate elements when being modelled inside the FE program.\n", "(e.g. Plate\\_1\\_2 & Plate\\_1\\_1: plate 1 with sub-element 1 and sub-element 2 respectively)\n", "\n", "It is the bending moment of these beam elements that we will work with and plot to see how they vary across the walls in each stage.\n", "\n", "\n", "\n", "The end goal of this plotting procedure is to give a quick overview of the results after a calculation has finished, and to be able to flip through the Construction Stages to easily compare them. \n", "\n", "There are a total of 19 Construction Stages in the dataset, 2 different types of outputs and 2 different plate elements, resulting in 76 plots.\n", "\n", "Each plot will look something like this, which shows the forces in Plate_1 for Construction Stage in phase 9: \n", "\n", "\n", "\n", "> **Note:** Understanding the structural/geotechnical context of the dataset is not important for solving the exercise. The idea of the exercise here is to familiarize yourself with data processing and visualization using Python. The same concepts could be used for all other types of datasets. If you will, you can look at it as generic data which is to be filtered and plotted. \n", "\n", "### The dataset\n", "\n", "All data files are saved in the folder 'Exercise 6B Data/Input Data'. For each construction stage and each type of result, there is a separate txt file (e.g. Phase 2_Table of total displacement.txt, Phase 2_Table of plate force envelopes.txt, etc.). Make sure to download all the datasets and save it in a folder. \n", "\n", "\n", "## The exercise\n", "The general structure of the script is given below and provides the basis for the exercise. \n", "\n", "***Many lines of code from the original script have been removed and the exercise consists of filling them in again.***\n", "\n", "All code comments from the original script have been retained as guidance through the exercise. \n", "\n", "The problem is partly about reading and understanding already written code and partly about writing code yourself. \n", "\n", "Reading other people's code plays a big role when collaboration on programming projects, and it's sometimes harder than writing the code yourself. Thus, it's a good exercise to get some exposure to this.\n", "\n", "Before starting, open some of the dataset files in the Input Data folder. Take a brief look at the contents of the file to get a feel for what you are working with. \n", "\n", "Copy this directly into your editor to use as a guide through the exercise. " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Import libraries \n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import glob\n", "import re\n", "\n", "# Set style for matplotlib plots\n", "plt.style.use('classic') " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Inputs " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Set style for matplotlib plots\n", "plt.style.use('classic') \n", "\n", "#Data Inputs\n", "\n", "# Find all file names of the files to be imported\n", "filenames = glob.glob('Exercise 6B Data/Input Data/*.txt')\n", "\n", "# Create an empty dataframe\n", "df_plate_bendingmoment = pd.DataFrame()\n", "\n", "# Loop through all filenames and append the data to the dataframe\n", "for file in filenames:\n", " # Get the name of the stage from the filename\n", " stage_name = re.search('Plate_ (.*?) \\(', file).group(1)\n", "\n", " # Import txt file to a temporary dataframe\n", " # \n", " \n", " # Create a new column in the temporary dataframe to store the stage name\n", " # \n", " \n", " # Append the temporary dataframe to the dataframe\n", " # \n", "\n", "# Inspect the column names and rename them if necessary\n", "# \n", "df_plate_bendingmoment.columns = ['Structural element', 'Node', 'Local number', 'x [m]', 'y [m]', 'N [kN/m]', 'N_min [kN/m]', \n", " 'N_max [kN/m]', 'Q [kN/m]', 'Q_min [kN/m]', 'Q_max [kN/m]', 'M [kN m/m]', 'M_min [kN m/m]', 'M_max [kN m/m]', 'stage_name']\n", "\n", " \n", "# Inspect the dataframes and check for the number of rows in the dataframe (there are supposed to be 2570 rows)\n", "# \n", "# " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Cleaning \n", "\n", "Upon further inspection, there are 2 issues with the data and we need to clean the data first:\n", "\n", "* The data in structural element column is not consistent and not fully populated with its respective structural element name,\n", "* Comma is used as decimals of the numbers and the type is string but not float." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Before we go to the data cleaning, lets remove irrelevant columns from the dataframe. \n", "# Since we are only interested in the bending moment, let's just keep the column structural element, stage_name, x [m], y [m] and M [kN/m]\n", "df_plate_bendingmoment = df_plate_bendingmoment[['Structural element', 'stage_name', 'x [m]', 'y [m]', 'M [kN m/m]']]\n", "display(df_plate_bendingmoment)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You should get something similar to below\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Issue 1: Inconsistent data in the column Structural element\n", "As seen in the figure below, the data in the column structural element is not fully populated and each row has different value for the same plate element (e.g. row 0 to 4 belong to Plate\\_1\\_1). The goal here is to populate the columns with the respective plates (e.g. row to 0 to 4 would contain Plate\\_1\\_1)\n", "\n", "Before: \n", "\n", "\n", "\n", "After:\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# From the figures above, we know that the data in the rows of multiplication of five consist of the plate name and numbers\n", "# we can then assign the plate number from each of the row of multiplication of five to the next 4 rows \n", "# (e.g. row 1-4 have the plate name and number of row 0, row 6-9 have the plate name and number of row 5, etc.)\n", "\n", "# Create a temporary list to store the structural element column from the dataframe\n", "structural_element_list = list(df_plate_bendingmoment['Structural element'])\n", "\n", "# Loop through each element in the list and change the element in list that does not show the correct plate number (e.g. element 1 to 4 in the list should be the same as element 0 and so on)\n", "for x,i in enumerate(structural_element_list):\n", " # \n", " \n", "# Assign the list back to the column in the original dataframe\n", "# \n", "display(df_plate_bendingmoment)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Issue 2: Incorrect decimal format and type\n", "Comma is used in the decimals and it should be converted to dot in Python. Further, the numbers are now of string type and they should be converted to float type." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Loop through each of the x[m], y[m] & M[kN m/m] columns\n", "for column in ['x [m]', 'y [m]', 'M [kN m/m]']:\n", " # Create a temporary list to store the data from each column\n", " temp_list = df_plate_bendingmoment[column]\n", " \n", " # Replace comma with dot for each element in the list\n", " # \n", " \n", " # Convert to float for each element in the list\n", " # \n", " \n", " # Assign the list back to the column in the original dataframe\n", " # " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Visualization" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Loop through each unique stage\n", "for stage in df_plate_bendingmoment['stage_name'].unique():\n", " #Loop through each plate member ['Plate\\\\\\_1', 'Plate\\\\\\_2']\n", " for plate in ['Plate\\\\\\_1', 'Plate\\\\\\_2']:\n", " # Filter the main dataframe, df_plate_bendingmoment, to only get rows with relevant stage and plate names \n", " # \n", " \n", " # Create a figure\n", " # \n", " \n", " # Plot the results\n", " # \n", "\n", " # Plot the grids\n", " # \n", "\n", " # Set titles, x- and y-labels\n", " # \n", " # \n", " # \n", " \n", " # Rotate figures in x-axis\n", " # \n", " \n", " # " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# End of exercises\n", "\n", "*The cell below is for setting the style of this document. It's not part of the exercises.*" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import HTML\n", "HTML(''.format(open('../css/cowi.css').read()))" ] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Python 3", "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.7.6" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 2 }