Skip to content

3.4 Plotting the data

Eric Breitbarth edited this page Aug 1, 2024 · 4 revisions

The exported nodemap.txt and connection.txt files from the GOM Aramis system can also be subsequently converted into the vtk (Visualization Toolkit) format. Simply use the following code:

# Imports
import os
from crackpy.fracture_analysis.data_processing import InputData
from crackpy.structure_elements.data_files import Nodemap
from crackpy.structure_elements.material import Material

# Settings
NODEMAP_FILE = 'Dummy2_WPXXX_DummyVersuch_2_dic_results_1_53.txt'
CONNECTION_FILE = 'Dummy2_WPXXX_DummyVersuch_2_dic_results_1_53_connections.txt'
NODEMAP_PATH = os.path.join('..', '..', 'test_data', 'crack_detection', 'Nodemaps')
CONNECTION_PATH = os.path.join('..', '..', 'test_data', 'crack_detection', 'Connections')
OUTPUT_PATH = os.path.join('..', '..', 'test_data', 'crack_detection', 'output', 'vtk')

# Get nodemap data
nodemap = Nodemap(name=NODEMAP_FILE, folder=NODEMAP_PATH)
material = Material(E=72000, nu_xy=0.33, sig_yield=350)
data = InputData(nodemap)
data.set_connection_file(CONNECTION_FILE, folder=CONNECTION_PATH)
data.calc_stresses(material)
data.calc_eps_vm()
mesh = data.to_vtk(OUTPUT_PATH)

PyVista plotter

The "data.to_vtk" method generates a vtk file or "pyvista.UnstructuredGrid" object containing mesh and facet data for analysis and visualisation of DIC results. The facet data includes displacement ( $u_{\mathrm{x}}$, $u_{\mathrm{y}}$, $u_{\mathrm{z}}$ ) and total strain data ( $\varepsilon_{\mathrm{xx}}$, $\varepsilon_{\mathrm{yy}}$, $\varepsilon_{\mathrm{xy}}$, $\varepsilon_{\mathrm{vm}}$, $\varepsilon_{\mathrm{1}}$, $\varepsilon_{\mathrm{2}}$ ) as well as stress data computed by Hooke's law ( $\sigma_{\mathrm{xx}}$, $\sigma_{\mathrm{yy}}$, $\sigma_{\mathrm{xy}}$, $\sigma_{\mathrm{vm}}$, $\sigma_{\mathrm{1}}$, $\sigma_{\mathrm{2}}$ ).

Plotting the mesh in Python is then fairly straightforward.

mesh.plot(scalars='eps_vm [%]',
          clim=[0, 0.5],
          cpos='xy',
          cmap='jet',
          show_bounds=True,
          lighting=True,
          show_scalar_bar=True,
          scalar_bar_args={'vertical': True},
          screenshot='eps_vm.png',
          off_screen=True
          )

The following scalar parameters are then available:

x [mm], y [mm], z [mm], u_x [mm], u_y [mm], u_z [mm], u_sum [mm], eps_x [%], eps_y [%], eps_xy [1], eps_vm [%], sig_x [MPa], sig_y [MPa], sig_xy [MPa], sig_vm [MPa]

PyVista_nodemap

A simple example of a vtk file imported into ParaView is shown below. ParaView_vtk

Matplotlib plotter

The mesh can also be plotted using matplotlib.

V1 - Based on data.connections

import matplotlib.pyplot as plt
import matplotlib.tri as mtri
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np

fmin = 0
fmax = 0.5
num_colors = 120
contour_vector = np.linspace(fmin, fmax, num_colors, endpoint=True)
label_vector = np.linspace(fmin, fmax, 6, endpoint=True)

plt.clf()
fig = plt.figure(1)
ax = fig.add_subplot(111)
triang = mtri.Triangulation(data.coor_x, data.coor_y, data.connections[:, 2:])
plot = ax.tricontourf(triang, data.eps_vm * 100.0, contour_vector, cmap='jet', extend='max')
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.2)
fig.colorbar(plot, ticks=label_vector, cax=cax, label='Von Mises eqv. strain [%]')
ax.legend(loc='upper right')
ax.set_xlabel('x [mm]')
ax.set_ylabel('y [mm]')
ax.axis('image')
ax.tick_params(axis='x', pad=15)
plt.savefig(os.path.join(OUTPUT_PATH, f"{NODEMAP_FILE[:-4]}.png"), bbox_inches='tight')

V2 - Based on PyVista object

# Plot mesh data with matplotlib and save to file
fmin = 0
fmax = 0.5
num_colors = 120
num_ticks = 6
contour_vector = np.linspace(fmin, fmax, num_colors, endpoint=True)
label_vector = np.linspace(fmin, fmax, num_ticks, endpoint=True)

plt.clf()
fig = plt.figure(1)
ax = fig.add_subplot(111)

# prepare data for tricontourf
x = mesh.points[:, 0]
y = mesh.points[:, 1]

# if no connection file is given, use faces, else use cells
if data.connections is None:
    triangles = mesh.faces.reshape((-1, 4))[:, 1:]
else:
    triangles = mesh.cells.reshape((-1, 4))[:, 1:]

# create triangles
triang = mtri.Triangulation(x, y, triangles)

# scalar data
scalar_data = mesh.point_data['eps_vm [%]']

# plot data using tricontourf
plot = ax.tricontourf(triang, scalar_data, contour_vector, cmap='jet', extend='max')

# Improve the look of the plot
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.2)
fig.colorbar(plot, ticks=label_vector, cax=cax, label='Von Mises eqv. strain [\\%]')
ax.set_xlabel('$x$ [mm]')
ax.set_ylabel('$y$ [mm]')
ax.axis('image')
ax.tick_params(axis='x', pad=15)

# Save plot to file
plt.savefig(os.path.join(OUTPUT_PATH, f"{NODEMAP_FILE[:-4]}.png"), bbox_inches='tight')

Dummy2_WPXXX_DummyVersuch_2_dic_results_1_53_mpl