Source code for opstool.pre.section._plot_fiber_sec

from typing import Optional, Union

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import PatchCollection

from ...utils import get_opensees_module

ops = get_opensees_module()


[docs] def vis_fiber_sec_real( ele_tag: int, sec_num: int = 1, color: Optional[str] = None, show_matTag: bool = False, highlight_matTag: Optional[Union[list[int], int]] = None, highlight_color: Union[list, str, tuple] = "k", ax=None, ): """ Visualizing the actual fiber section data, where only the fiber center coordinates and areas are demonstrated, represents the data used in analysis. .. Note:: This is applicable for 3D only and not for 2D! Parameters ---------- ele_tag : int The element ID to which the section belongs, for display purposes. sec_num : int The section at which Gauss points to display, numbered starting from 1, from i to segment j. color: str, optional Defaults to gradient colors, varying based on the distance to the section's center point. show_matTag : bool, optional Whether to show the material tag on the fiber. Defaults to False. highlight_matTag : float or list of floats The material tag to highlight, if any. Defaults to None. If listed, then highlight all the materials in the list. highlight_color : str or array-like, optional Color for highlight_matTag. Defaults to gradient colors, varying based on the distance to the section's center point. ax : matplotlib.axes.Axes, optional The axes to plot the section. Defaults to None. """ FiberData = ops.eleResponse(ele_tag, "section", "fiberData2", sec_num) # "yCoord", "zCoord", "area", "matTag" "stress", "strain" FiberData = np.array(FiberData).reshape((-1, 6)) ylocs, zlocs, areas = FiberData[:, 0], FiberData[:, 1], FiberData[:, 2] mats = FiberData[:, 3].astype(int) # ymin, ymax = np.min(ylocs), np.max(ylocs) zmin, zmax = np.min(zlocs), np.max(zlocs) ymean, zmean = np.mean(ylocs), np.mean(zlocs) aspect_ratio = (zmax - zmin) / (ymax - ymin) if aspect_ratio <= 0.333: aspect_ratio = 0.333 if aspect_ratio >= 3: aspect_ratio = 3 figsize = (8, 8) if aspect_ratio < 1 else (6, 6 * aspect_ratio) if ax is None: with plt.style.context("fivethirtyeight"): fig, ax = plt.subplots(figsize=figsize) with plt.style.context("fivethirtyeight"): patches = [plt.Circle((yloc, zloc), np.sqrt(area / np.pi)) for yloc, zloc, area in zip(ylocs, zlocs, areas)] if show_matTag: for yloc, zloc, mat in zip(ylocs, zlocs, mats): ax.text( yloc, zloc, f"{mat}", ha="center", va="center", fontsize=12, ) coll = PatchCollection(patches, alpha=0.75) if color is None: colors = (ylocs - ymean) ** 2 + (zlocs - zmean) ** 2 coll.set_array(colors) else: coll.set_color(color) ax.add_collection(coll) if highlight_matTag is not None: highlight_matTag = np.atleast_1d(highlight_matTag) highlight_color = np.atleast_1d(highlight_color) for mtag, color in zip(highlight_matTag, highlight_color): idx = np.argwhere(np.abs(mats - mtag) < 1e-6) rebar_ys = ylocs[idx] rebar_zs = zlocs[idx] rebar_areas = areas[idx] patches_rebar = [ plt.Circle((yloc, zloc), np.sqrt(area / np.pi)) for yloc, zloc, area in zip(rebar_ys, rebar_zs, rebar_areas) ] coll_rebar = PatchCollection(patches_rebar, color=color, alpha=1) ax.add_collection(coll_rebar) if aspect_ratio == 1: ax.set_aspect("equal") ax.set_xlim(ymin * 1.5, ymax * 1.5) ax.set_ylim(zmin * 1.5, zmax * 1.5) ax.set_xlabel("y", fontsize=20) ax.set_ylabel("z", fontsize=20) ax.autoscale() plt.xticks(fontsize=12) plt.yticks(fontsize=12)