def make_available_sensors_plot(c: Config, pier_radius: float, track_radius: float, edge_radius: float): """Scatter plot of sensors used for classification.""" top_view_bridge(c.bridge, abutments=True, piers=True, compass=False) plot_deck_sensors( c=c, without=without.points( c=c, pier_radius=pier_radius, track_radius=track_radius, edge_radius=edge_radius, ), label=True, ) for l_i, load in enumerate([Point(x=21, z=-8.4), Point(x=33, z=-4)]): plt.scatter( [load.x], [load.z], color="red", marker="o", s=50, label="Sensor of interest" if l_i == 0 else None, ) legend_marker_size(plt.legend(), 50) plt.title(f"Sensors available for classification on Bridge 705") plt.tight_layout() plt.savefig(c.get_image_path("sensors", "unavailable-sensors.pdf")) plt.close()
def temperature_effect_date(c: Config, month: str, vert: bool): temp = __init__.load(name=month) point = Point(x=51, y=0, z=-8.4) plt.landscape() def plot_hours(): if not vert: return label_set = False for dt in temp["datetime"]: if np.isclose(float(dt.hour + dt.minute), 0): label = None if not label_set: label = "Time at vertical line = 00:00" label_set = True plt.axvline(x=dt, linewidth=1, color="black", label=label) # Plot the temperature. plt.subplot(2, 1, 1) plot_hours() plt.scatter( temp["datetime"], temp["temp"], c=temp["missing"], cmap=mpl.cm.get_cmap("bwr"), s=1, ) plt.ylabel("Temperature (°C)") plt.xlabel("Date") plt.gcf().autofmt_xdate() plt.title(f"Temperature in {str(month[0]).upper()}{month[1:]}") plt.legend() # Plot the effect at a point. response_type = ResponseType.YTranslation plt.subplot(2, 1, 2) plot_hours() effect = __init__.effect( c=c, response_type=response_type, points=[point], temps=temp["temp"] )[0] plt.scatter( temp["datetime"], effect * 1000, c=temp["missing"], cmap=mpl.cm.get_cmap("bwr"), s=1, ) plt.ylabel(f"{response_type.name()} (mm)") plt.xlabel("Date") plt.gcf().autofmt_xdate() plt.title(f"{response_type.name()} to unit thermal loading in {month}") # Save. plt.tight_layout() plt.savefig(c.get_image_path("classify/temperature", f"{month}.png")) plt.savefig(c.get_image_path("classify/temperature", f"{month}.pdf")) plt.close()
def plot_deck_sensors(c: Config, without: Callable[[Point], bool], label: bool = False): """Scatter plot of deck sensors.""" deck_nodes, _ = get_bridge_nodes(c.bridge) deck_nodes = det_nodes(deck_nodes) unavail_nodes = [] avail_nodes = [] for node in deck_nodes: if without(Point(x=node.x, y=node.y, z=node.z)): unavail_nodes.append(node) else: avail_nodes.append(node) X, Z, H = [], [], [] # 2D arrays, x and z coordinates, and height. for node in deck_nodes: X.append(node.x) Z.append(node.z) if without(Point(x=node.x, y=node.y, z=node.z)): H.append(1) else: H.append(0) plt.scatter( [node.x for node in avail_nodes], [node.z for node in avail_nodes], s=5, color="#1f77b4", ) plt.scatter( [node.x for node in unavail_nodes], [node.z for node in unavail_nodes], color="#ff7f0e", s=5, ) if label: plt.scatter( [avail_nodes[0].x], [avail_nodes[0].z], color="#1f77b4", label="Available", s=5, ) plt.scatter( [unavail_nodes[0].x], [unavail_nodes[0].z], color="#ff7f0e", label="Unavailable", s=5, ) legend = plt.legend() legend_marker_size(legend, 50)
def plot_contour_deck( c: Config, responses: Responses, point_loads: List[PointLoad] = [], units: Optional[str] = None, cmap=default_cmap, norm=None, scatter: bool = False, levels: int = 14, mm_legend: bool = True, mm_legend_without_f: Optional[Callable[[Point], bool]] = None, sci_format: bool = False, decimals: int = 4, y: float = 0, ): """Contour or scatter plot of simulation responses. Args: config: simulation configuration object. responses: the simulation responses to plot. units: optional units string for the colourbar. cmap: Matplotlib colormap to use for colouring responses. norm: Matplotlib norm to use for colouring responses. scatter: scatter plot instead of contour plot? levels: levels in the contour plot. mm_legend: plot a legend of min and max values? mm_legend_without_f: function to filter points considered in the legend. sci_format: force scientific formatting (E) in the legend. decimals: round legend values to this many decimals. """ amax, amax_x, amax_z = -np.inf, None, None amin, amin_x, amin_z = np.inf, None, None X, Z, H = [], [], [] # 2D arrays, x and z coordinates, and height. # Begin structure data. def structure_data(responses): nonlocal amax nonlocal amax_x nonlocal amax_z nonlocal amin nonlocal amin_x nonlocal amin_z nonlocal X nonlocal Z nonlocal H # First reset the maximums and minimums. amax, amax_x, amax_z = -np.inf, None, None amin, amin_x, amin_z = np.inf, None, None X, Z, H = [], [], [] for x in responses.xs: # There is a chance that no sensors exist at given y position for every # x position, thus we must check. if y in responses.zs[x]: for z in responses.zs[x][y]: X.append(x) Z.append(z) H.append(responses.responses[0][x][y][z]) if H[-1] > amax: amax = H[-1] amax_x, amax_z = X[-1], Z[-1] if H[-1] < amin: amin = H[-1] amin_x, amin_z = X[-1], Z[-1] print(f"amin, amax = {amin}, {amax}") structure_data(responses) if len(X) == 0: raise ValueError(f"No fem for contour plot") # Plot fem, contour or scatter plot. if scatter: cs = plt.scatter( x=np.array(X).flatten(), y=np.array(Z).flatten(), c=np.array(H).flatten(), cmap=cmap, norm=norm, s=1, ) else: cs = plt.tricontourf(X, Z, H, levels=levels, cmap=cmap, norm=norm) # Colourbar, maybe using given norm. clb = plt.colorbar(cs, norm=norm) if units is not None: clb.ax.set_title(units) # Plot point loads. for pload in point_loads: x = pload.x z = pload.z plt.scatter( [x], [z], label=f"{pload.load} kN load", marker="o", color="black", ) # Begin: min, max legend. if mm_legend or mm_legend_without_f is not None: if mm_legend_without_f is not None: structure_data(responses.without(mm_legend_without_f)) # Plot min and max fem. amin_s = (f"{amin:.{decimals}g}" if sci_format else f"{np.around(amin, decimals)}") amax_s = (f"{amax:.{decimals}g}" if sci_format else f"{np.around(amax, decimals)}") aabs_s = (f"{amin - amax:.{decimals}g}" if sci_format else f"{np.around(abs(amin - amax), decimals)}") units_str = "" if units is None else f" {units}" print(units_str) for point, label, color, alpha in [ ((amin_x, amin_z), f"min = {amin_s} {units_str}", "orange", 0), ((amax_x, amax_z), f"max = {amax_s} {units_str}", "green", 0), ((amin_x, amin_z), f"|min-max| = {aabs_s} {units_str}", "red", 0), ]: plt.scatter( [point[0]], [point[1]], label=label, marker="o", color=color, alpha=alpha, ) # End: min, max legend. plt.xlabel("X position") plt.ylabel("Z position")
def comparison_plots_705(c: Config, run_only: bool, scatter: bool): """Make contour plots for all verification points on bridge 705.""" # from classify.scenario.bridge import transverse_crack # c = transverse_crack().use(c)[0] positions = [ # (52, -8.4, "a"), (34.95459, 26.24579 - 16.6, "a"), (51.25051, 16.6 - 16.6, "b"), (89.98269, 9.445789 - 16.6, "c"), (102.5037, 6.954211 - 16.6, "d"), # (34.95459, 29.22606 - 16.6, "a"), # (51.25051, 16.6 - 16.6, "b"), # (92.40638, 12.405 - 16.6, "c"), # (101.7649, 3.973938 - 16.6, "d"), ] diana_values = pd.read_csv("validation/diana-screenshots/min-max.csv") response_types = [ResponseType.YTranslation, ResponseType.Strain] # For each response type and loading position first create contour plots for # OpenSees. Then finally create subplots comparing to Diana. cmap = diana_cmap_r for load_x, load_z, label in positions: for response_type in response_types: # Setup the metadata. if response_type == ResponseType.YTranslation: rt_str = "displa" unit_str = "mm" elif response_type == ResponseType.Strain: rt_str = "strain" unit_str = "E-6" else: raise ValueError("Unsupported response type") row = diana_values[diana_values["name"] == f"{label}-{rt_str}"] dmin, dmax = float(row["dmin"]), float(row["dmax"]) omin, omax = float(row["omin"]), float(row["omax"]) amin, amax = max(dmin, omin), min(dmax, omax) levels = np.linspace(amin, amax, 16) # Create the OpenSees plot. loads = [ PointLoad( x_frac=c.bridge.x_frac(load_x), z_frac=c.bridge.z_frac(load_z), kn=100, ) ] fem_responses = load_fem_responses( c=c, response_type=response_type, sim_runner=OSRunner(c), sim_params=SimParams(ploads=loads, response_types=response_types), ) if run_only: continue title = ( f"{response_type.name()} from a {loads[0].kn} kN point load at" + f"\nx = {load_x:.3f}m, z = {load_z:.3f}m, with ") save = lambda prefix: c.get_image_path( "validation/diana-comp", safe_str(f"{prefix}{response_type.name()}") + ".pdf", ) top_view_bridge(c.bridge, piers=True, abutments=True) fem_responses = fem_responses.resize() sci_format = response_type == ResponseType.Strain plot_contour_deck( c=c, responses=fem_responses, ploads=loads, cmap=cmap, levels=levels, sci_format=sci_format, decimals=4, scatter=scatter, ) plt.title(title + "OpenSees") plt.tight_layout() plt.savefig(save(f"{label}-")) plt.close() # Finally create label/title the Diana plot. if label is not None: # First plot and clear, just to have the same colorbar. plot_contour_deck(c=c, responses=fem_responses, ploads=loads, cmap=cmap, levels=levels) plt.cla() # Then plot the bridge and top_view_bridge(c.bridge, piers=True, abutments=True) plt.imshow( mpimg.imread( f"validation/diana-screenshots/{label}-{rt_str}.png"), extent=( c.bridge.x_min, c.bridge.x_max, c.bridge.z_min, c.bridge.z_max, ), ) dmin_s = f"{dmin:.4e}" if sci_format else f"{dmin:.4f}" dmax_s = f"{dmax:.4e}" if sci_format else f"{dmax:.4f}" dabs_s = (f"{abs(dmin - dmax):.4e}" if sci_format else f"{abs(dmin - dmax):.4f}") for point, leg_label, color, alpha in [ ((load_x, load_z), f"{loads[0].kn} kN load", "r", 1), ((0, 0), f"min = {dmin_s} {fem_responses.units}", "r", 0), ((0, 0), f"max = {dmax_s} {fem_responses.units}", "r", 0), ((0, 0), f"|min-max| = {dabs_s} {fem_responses.units}", "r", 0), ]: plt.scatter( [point[0]], [point[1]], label=leg_label, marker="o", color=color, alpha=alpha, ) plt.legend() plt.title(title + "Diana") plt.xlabel("X position (m)") plt.ylabel("Z position (m)") plt.tight_layout() plt.savefig(save(f"{label}-diana-")) plt.close()
def piers_displaced(c: Config): """Contour plots of pier displacement for the given pier indices.""" pier_indices = [4, 5] response_types = [ResponseType.YTranslation, ResponseType.Strain] axis_values = pd.read_csv("validation/axis-screenshots/piers-min-max.csv") for r_i, response_type in enumerate(response_types): for p in pier_indices: # Run the simulation and collect fem. sim_responses = load_fem_responses( c=c, response_type=response_type, sim_runner=OSRunner(c), sim_params=SimParams(displacement_ctrl=PierSettlement( displacement=c.pd_unit_disp, pier=p), ), ) # In the case of stress we map from kn/m2 to kn/mm2 (E-6) and then # divide by 1000, so (E-9). assert c.pd_unit_disp == 1 if response_type == ResponseType.Strain: sim_responses.to_stress(c.bridge).map(lambda r: r * 1e-9) # Get min and max values for both Axis and OpenSees. rt_str = ("displa" if response_type == ResponseType.YTranslation else "stress") row = axis_values[axis_values["name"] == f"{p}-{rt_str}"] dmin, dmax = float(row["dmin"]), float(row["dmax"]) omin, omax = float(row["omin"]), float(row["omax"]) amin, amax = max(dmin, omin), min(dmax, omax) levels = np.linspace(amin, amax, 16) # Plot and save the image. If plotting strains use Axis values for # colour normalization. # norm = None from plot import axis_cmap_r cmap = axis_cmap_r top_view_bridge(c.bridge, abutments=True, piers=True) plot_contour_deck(c=c, cmap=cmap, responses=sim_responses, levels=levels) plt.tight_layout() plt.title( f"{sim_responses.response_type.name()} from 1mm pier settlement with OpenSees" ) plt.savefig( c.get_image_path( "validation/pier-displacement", safe_str(f"pier-{p}-{sim_responses.response_type.name()}") + ".pdf", )) plt.close() # First plot and clear, just to have the same colorbar. plot_contour_deck(c=c, responses=sim_responses, cmap=cmap, levels=levels) plt.cla() # Save the axis plots. axis_img = mpimg.imread( f"validation/axis-screenshots/{p}-{rt_str}.png") top_view_bridge(c.bridge, abutments=True) plt.imshow( axis_img, extent=( c.bridge.x_min, c.bridge.x_max, c.bridge.z_min, c.bridge.z_max, ), ) # Plot the load and min, max values. for point, leg_label, color in [ ((0, 0), f"min = {np.around(dmin, 3)} {sim_responses.units}", "r"), ((0, 0), f"max = {np.around(dmax, 3)} {sim_responses.units}", "r"), ( (0, 0), f"|min-max| = {np.around(abs(dmax - dmin), 3)} {sim_responses.units}", "r", ), ]: plt.scatter( [point[0]], [point[1]], label=leg_label, marker="o", color=color, alpha=0, ) if response_type == ResponseType.YTranslation: plt.legend() # Title and save. plt.title( f"{response_type.name()} from 1mm pier settlement with AxisVM") plt.xlabel("X position (m)") plt.ylabel("Z position (m)") plt.tight_layout() plt.savefig( c.get_image_path( "validation/pier-displacement", f"{p}-axis-{rt_str}.pdf", )) plt.close()