Shear force and bending moment diagram
Structural Engineering
Example from the compendium of canonical charts
Python Code
"""Structural Engineering — Shear force and bending moment diagram."""
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
L = 6.0 # beam length (m)
w = 5.0 # UDL (kN/m)
def generate():
x = np.linspace(0, L, 300)
# Simply-supported beam with UDL
R = w * L / 2 # reaction at each support
V = R - w * x # shear force
M = R * x - w * x**2 / 2 # bending moment
M_max = w * L**2 / 8 # at midspan
fig = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.10,
subplot_titles=["Shear Force Diagram", "Bending Moment Diagram"],
)
# Row 1: Shear force
fig.add_trace(go.Scatter(
x=x, y=V,
mode="lines",
line=dict(color=VIOLET, width=2.5),
fill="tozeroy",
fillcolor="rgba(132, 94, 238, 0.18)",
name="Shear V(x)",
hovertemplate="x=%{x:.2f} m<br>V=%{y:.2f} kN<extra></extra>",
), row=1, col=1)
# Annotate peak shear at x=0 and x=L
fig.add_annotation(x=0, y=R, text=f"+{R:.1f} kN", showarrow=True,
arrowhead=2, ax=30, ay=-20, row=1, col=1,
font=dict(size=10))
fig.add_annotation(x=L, y=-R, text=f"−{R:.1f} kN", showarrow=True,
arrowhead=2, ax=-30, ay=20, row=1, col=1,
font=dict(size=10))
# Row 2: Bending moment (sagging positive, plotted downward convention — use positive)
fig.add_trace(go.Scatter(
x=x, y=M,
mode="lines",
line=dict(color=GREEN, width=2.5),
fill="tozeroy",
fillcolor="rgba(85, 182, 133, 0.18)",
name="Moment M(x)",
hovertemplate="x=%{x:.2f} m<br>M=%{y:.2f} kN·m<extra></extra>",
), row=2, col=1)
# Annotate max moment at midspan
fig.add_annotation(
x=L/2, y=M_max,
text=f"M<sub>max</sub> = wL²/8 = {M_max:.1f} kN·m",
showarrow=True, arrowhead=2,
ax=0, ay=-35,
row=2, col=1,
font=dict(size=11),
)
fig.update_xaxes(title_text="Position (m)", row=2, col=1)
fig.update_yaxes(title_text="Shear (kN)", row=1, col=1)
fig.update_yaxes(title_text="Moment (kN·m)", row=2, col=1)
fig.update_layout(
legend=dict(orientation="h", y=-0.12),
margin=dict(t=70, b=60, l=80, r=40),
annotations=fig.layout.annotations + (
dict(
x=0.5, y=1.04, xref="paper", yref="paper",
text=f"Simply-supported beam: L={L} m, w={w} kN/m (UDL)",
showarrow=False, font=dict(size=11, color="#60646c"),
),
),
)
return fig
if __name__ == "__main__":
generate()
Made with Plotly