Skip to content

Commit

Permalink
New plotting options for truss
Browse files Browse the repository at this point in the history
  • Loading branch information
cmccomb committed Jan 3, 2024
1 parent 2b2fa7c commit 4415942
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 7 deletions.
6 changes: 5 additions & 1 deletion tests/test_construction_and_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ def test_demo_report(self):
# Build truss from file
truss_from_file = trussme.read_trs(TEST_TRUSS_FILENAME)

trussme.report_to_md("asdf.md", truss_from_file, trussme.Goals())
trussme.report_to_md(
os.path.join(os.path.dirname(__file__), "asdf.md"),
truss_from_file,
trussme.Goals(),
)

def test_build_methods(self):
goals = trussme.Goals(
Expand Down
9 changes: 8 additions & 1 deletion trussme/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ def __generate_stress_analysis(truss, goals, with_figures: bool = True) -> str:

# Print information about members
analysis += "\n## FORCES AND STRESSES\n"

if with_figures:
analysis += trussme.visualize.plot_truss(truss, starting_shape="force") + "\n"

data = []
rows = []
for m in truss.members:
Expand Down Expand Up @@ -430,7 +434,10 @@ def __generate_stress_analysis(truss, goals, with_figures: bool = True) -> str:
analysis += "\n## DEFLECTIONS\n"

if with_figures:
analysis += trussme.visualize.plot_truss(truss, deflected_shape=True) + "\n"
analysis += (
trussme.visualize.plot_truss(truss, starting_shape="k", deflected_shape="m")
+ "\n"
)

data = []
rows = []
Expand Down
46 changes: 41 additions & 5 deletions trussme/visualize.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
import matplotlib.pyplot
import io
import re
import numpy
from typing import Union, Literal


def plot_truss(
truss, deflected_shape: bool = False, exaggeration_factor: float = 10
truss,
starting_shape: Union[
None, Literal["fos", "force", "b", "g", "r", "c", "m", "y", "k"]
] = "k",
deflected_shape: Union[
None, Literal["fos", "force", "b", "g", "r", "c", "m", "y", "k"]
] = None,
exaggeration_factor: float = 10,
fos_threshold: float = 1.0,
) -> str:
"""Plot the truss.
Parameters
----------
truss: Truss
The truss to plot.
deflected_shape: bool, default=False
Whether to plot the deflected shape.
starting_shape: : Union[None, Literal["fos", "force", "b", "g", "r", "c", "m", "y", "k"]], default="k"
How to show the starting shape. If None, the starting shape is not shown. If "fos", the members are colored
green if the factor of safety is above the threshold and red if it is below. If "force", the members are colored
according to the force in the member. If a color, the members are colored that color.
deflected_shape: : Union[None, Literal["fos", "force", "b", "g", "r", "c", "m", "y", "k"]], default = None
How to show the deflected shape. If None, the starting shape is not shown. If "fos", the members are colored
green if the factor of safety is above the threshold and red if it is below. If "force", the members are colored
according to the force in the member. If a color, the members are colored that color.
exaggeration_factor: float, default=10
The factor by which to exaggerate the deflected shape.
fos_threshold: float, default=1.0
The threshold for the factor of safety. If the factor of safety is below this value, the member is colored red.
Returns
-------
Expand All @@ -30,15 +48,33 @@ def plot_truss(
ax.axis("equal")
ax.set_axis_off()

scaler: float = numpy.max(numpy.abs([member.force for member in truss.members]))

for member in truss.members:
if starting_shape == "fos":
color = "g" if member.fos > fos_threshold else "r"
elif starting_shape == "force":
color = matplotlib.pyplot.cm.bwr(member.force / (2 * scaler) + 0.5)
elif starting_shape is None:
break
else:
color = starting_shape
ax.plot(
[member.begin_joint.coordinates[0], member.end_joint.coordinates[0]],
[member.begin_joint.coordinates[1], member.end_joint.coordinates[1]],
color="k",
color=color,
)

if deflected_shape:
for member in truss.members:
if starting_shape == "fos":
color = "g" if member.fos > fos_threshold else "r"
elif starting_shape == "force":
color = matplotlib.pyplot.cm.bwr(member.force / (2 * scaler) + 0.5)
elif starting_shape is None:
break
else:
color = starting_shape
ax.plot(
[
member.begin_joint.coordinates[0]
Expand All @@ -52,7 +88,7 @@ def plot_truss(
member.end_joint.coordinates[1]
+ exaggeration_factor * member.end_joint.deflections[1],
],
color="m",
color=color,
)

imgdata = io.StringIO()
Expand Down

0 comments on commit 4415942

Please sign in to comment.