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.
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/)
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. Note that each plate element consists of multiple smaller plate elements when being modelled inside the FE program. (e.g. Plate_1_2 & Plate_1_1: plate 1 with sub-element 1 and sub-element 2 respectively)
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.
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.
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.
Each plot will look something like this, which shows the forces in Plate_1 for Construction Stage in phase 9:
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.
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.
The general structure of the script is given below and provides the basis for the exercise.
*Many lines of code from the original script have been removed and the exercise consists of filling them in again.*
All code comments from the original script have been retained as guidance through the exercise.
The problem is partly about reading and understanding already written code and partly about writing code yourself.
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.
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.
Copy this directly into your editor to use as a guide through the exercise.
# Import libraries
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import glob
import re
# Set style for matplotlib plots
plt.style.use('classic')
# Set style for matplotlib plots
plt.style.use('classic')
#Data Inputs
# Find all file names of the files to be imported
filenames = glob.glob('Exercise 6B Data/Input Data/*.txt')
# Create an empty dataframe
df_plate_bendingmoment = pd.DataFrame()
# Loop through all filenames and append the data to the dataframe
for file in filenames:
# Get the name of the stage from the filename
stage_name = re.search('Plate_ (.*?) \(', file).group(1)
# Import txt file to a temporary dataframe
# <Code here!>
# Create a new column in the temporary dataframe to store the stage name
# <Code here!>
# Append the temporary dataframe to the dataframe
# <Code here!>
# Inspect the column names and rename them if necessary
# <Code here!>
df_plate_bendingmoment.columns = ['Structural element', 'Node', 'Local number', 'x [m]', 'y [m]', 'N [kN/m]', 'N_min [kN/m]',
'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']
# Inspect the dataframes and check for the number of rows in the dataframe (there are supposed to be 2570 rows)
# <Code here!>
# <Code here!>
Upon further inspection, there are 2 issues with the data and we need to clean the data first:
# Before we go to the data cleaning, lets remove irrelevant columns from the dataframe.
# 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]
df_plate_bendingmoment = df_plate_bendingmoment[['Structural element', 'stage_name', 'x [m]', 'y [m]', 'M [kN m/m]']]
display(df_plate_bendingmoment)
You should get something similar to below
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)
Before:
After:
# From the figures above, we know that the data in the rows of multiplication of five consist of the plate name and numbers
# we can then assign the plate number from each of the row of multiplication of five to the next 4 rows
# (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.)
# Create a temporary list to store the structural element column from the dataframe
structural_element_list = list(df_plate_bendingmoment['Structural element'])
# 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)
for x,i in enumerate(structural_element_list):
# <Code here!>
# Assign the list back to the column in the original dataframe
# <Code here!>
display(df_plate_bendingmoment)
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.
# Loop through each of the x[m], y[m] & M[kN m/m] columns
for column in ['x [m]', 'y [m]', 'M [kN m/m]']:
# Create a temporary list to store the data from each column
temp_list = df_plate_bendingmoment[column]
# Replace comma with dot for each element in the list
# <Code here!>
# Convert to float for each element in the list
# <Code here!>
# Assign the list back to the column in the original dataframe
# <Code here!>
#Loop through each unique stage
for stage in df_plate_bendingmoment['stage_name'].unique():
#Loop through each plate member ['Plate\\\_1', 'Plate\\\_2']
for plate in ['Plate\\\_1', 'Plate\\\_2']:
# Filter the main dataframe, df_plate_bendingmoment, to only get rows with relevant stage and plate names
# <Code here!>
# Create a figure
# <Code here!>
# Plot the results
# <Code here!>
# Plot the grids
# <Code here!>
# Set titles, x- and y-labels
# <Code here!>
# <Code here!>
# <Code here!>
# Rotate figures in x-axis
# <Code here!>
# <Code here!>
The cell below is for setting the style of this document. It's not part of the exercises.
from IPython.display import HTML
HTML('<style>{}</style>'.format(open('../css/cowi.css').read()))