-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathplotting_functions.py
More file actions
391 lines (299 loc) · 14.1 KB
/
plotting_functions.py
File metadata and controls
391 lines (299 loc) · 14.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MultipleLocator
from mpl_toolkits.axes_grid1.inset_locator import inset_axes, mark_inset
from matplotlib.patches import Polygon
def set_plot_style():
"""
Set the common plotting style for all plots.
"""
plt.rc('text', usetex=True)
plt.rc('font', family='serif', size=11)
def plot_contours(contours):
set_plot_style()
fig, ax = plt.subplots(figsize=(8 / 1.2, 5 / 1.2))
for contour in contours:
contour = contour.squeeze(axis=1) # Remove unnecessary axis
plt.plot(contour[:, 0], contour[:, 1], linewidth=2) # Plot each contour
ax.set_xlabel(r'$x$ (px)')
ax.set_ylabel(r'$y$ (px)')
ax.set_aspect('equal') # Ensure equal scaling on both axes
fig.tight_layout()
plt.savefig('images/pdf/wall_contours.pdf')
plt.show()
# Corrected for Article
def plot_binary_image(binary_image):
set_plot_style()
fig, ax = plt.subplots(figsize=(8 / 1.2, 5 / 1.2))
ax.imshow(binary_image, cmap='gray', origin='lower')
ax.set_xlabel(r'$x$ (px)')
ax.set_ylabel(r'$y$ (px)')
fig.tight_layout()
plt.savefig('images/pdf/wall_mask.pdf')
plt.show()
def plot_histogram(grid_full, x_values_full, y_values_full):
plt.imshow(grid_full, origin='lower',
extent=[x_values_full[0], x_values_full[-1], y_values_full[0], y_values_full[-1]], cmap='viridis')
plt.colorbar(label='Density')
plt.xlabel('X Coordinate')
plt.ylabel('Y Coordinate')
plt.show()
def plot_segments(segments, color='blue', label=None):
for segment in segments:
x_values = [segment[0][0], segment[1][0]]
y_values = [segment[0][1], segment[1][1]]
plt.plot(x_values, y_values, color=color, label=label)
plt.xlabel('X Coordinate')
plt.ylabel('Y Coordinate')
plt.title('Plot of Segments')
plt.grid(True)
plt.show()
def plot_segments_with_random_colors(segments, name=None):
set_plot_style()
fig, ax = plt.subplots(figsize=(8 / 1.2, 5 / 1.2))
num_segments = len(segments)
random_colors = [np.random.rand(3, ) for _ in range(num_segments)]
for segment, color in zip(segments, random_colors):
x_values = [segment[0][0], segment[1][0]]
y_values = [segment[0][1], segment[1][1]]
ax.plot(x_values, y_values, color=color)
ax.set_xlabel(r'$x$ (m)')
ax.set_ylabel(r'$y$ (m)')
fig.tight_layout()
plt.savefig(f'images/pdf/{name}.pdf')
plt.show()
def plot_2d_wall_groups(wall_groups, rotated_wall_groups, rotated_wall_axes, original_wall_axes):
plt.figure()
# Plotting original wall groups
for i, wall_group in enumerate(wall_groups):
wall_group_x, wall_group_y = zip(*[(x, y) for x, y, _ in wall_group])
plt.plot(wall_group_x, wall_group_y, label=f'Wall Group {i + 1} (Original)')
# Plotting rotated wall groups
for i, rotated_wall_group in enumerate(rotated_wall_groups):
rotated_wall_group_x, rotated_wall_group_y = zip(*[(x, y) for x, y, _ in rotated_wall_group])
plt.plot(rotated_wall_group_x, rotated_wall_group_y, '--', label=f'Wall Group {i + 1} (Rotated)')
# Plotting rotated wall axes
for i, rotated_wall_axis in enumerate(rotated_wall_axes):
# Projecting the 3D points onto the XY plane
rotated_wall_axis_xy = [(x, y) for x, y, _ in rotated_wall_axis]
# Extracting X and Y coordinates for plotting
rotated_wall_axis_x, rotated_wall_axis_y = zip(*rotated_wall_axis_xy)
# Plotting rotated wall axes in 2D
plt.plot(rotated_wall_axis_x, rotated_wall_axis_y, 'b-', label=f'Rotated Axis {i + 1}')
# Plotting original wall axes
for j, original_wall_axis in enumerate(original_wall_axes):
# If Z coordinate is available, use it, otherwise ignore it
if len(original_wall_axis) == 3:
original_wall_axis_xy = [(x, y) for x, y, _ in original_wall_axis]
else:
original_wall_axis_xy = original_wall_axis # Just use X and Y
# Extracting X and Y coordinates for plotting
original_wall_axis_x, original_wall_axis_y = zip(*original_wall_axis_xy)
# Plotting original wall axes in 2D
plt.plot(original_wall_axis_x, original_wall_axis_y, 'r--', label=f'Original Axis {j + 1}')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.grid(True)
plt.title('2D Plot of Wall Groups')
plt.show()
def plot_threshold_and_filtered_points(threshold, wall_group, filtered_wall_points):
# Extract y-coordinates from wall_group
y_coordinates = [point[1] for point in wall_group]
# Plot the threshold
plt.axhline(y=threshold, color='r', linestyle='--', label='Threshold')
# Plot the wall points and the filtered wall points
plt.scatter(y_coordinates, [0] * len(y_coordinates), color='b', label='Wall Points')
plt.scatter([point[1] for point in filtered_wall_points], [0] * len(filtered_wall_points), color='g',
label='Filtered Wall Points')
# Add labels and legend
plt.xlabel('Y-coordinate')
plt.ylabel('Z-coordinate')
plt.title('Threshold and Filtered Wall Points')
plt.legend()
plt.grid(True)
# Show plot
plt.show()
def plot_histogram_with_threshold(hist, height_threshold):
# Vykreslení histogramu
plt.figure(figsize=(10, 6))
bin_edges = np.arange(len(hist) + 1) # Hrany binů
plt.bar(bin_edges[:-1], hist, width=1, align='edge', color='blue', alpha=0.7, label='Histogram')
# Vykreslení thresholdu
plt.axhline(y=height_threshold, color='red', linestyle='--', label='Threshold')
# Nastavení popisků a legendy
plt.xlabel('Bins')
plt.ylabel('Counts')
plt.title('Histogram s Thresholdem')
plt.legend()
# Zobrazení grafu
plt.show()
def plot_smoothed_contour(original_polygon, smoothed_polygon):
set_plot_style()
fig, ax = plt.subplots(figsize=(8/1.2, 5/1.2))
tick_interval = 4 # Interval for major ticks on the axes
ax.yaxis.set_major_locator(MultipleLocator(tick_interval))
ax.xaxis.set_major_locator(MultipleLocator(tick_interval))
# Original contour
ax.add_patch(original_polygon)
# Smoothed contour
ax.add_patch(smoothed_polygon)
# Plot points
x_contour, y_contour = original_polygon.get_xy().T
x_smoothed, y_smoothed = smoothed_polygon.get_xy().T
ax.scatter(x_contour, y_contour, s=2, color='blue')
ax.scatter(x_smoothed, y_smoothed, s=2, color='red')
# Main plot settings
# ax.legend(['Original Contour', 'Smoothed Contour'], loc='lower left')
ax.set_aspect('equal', 'box')
plt.xlabel(r'$x$ (m)')
plt.ylabel(r'$y$ (m)')
fig.tight_layout()
# Define the zoom region (let's focus on a quarter of the smoothed polygon)
zoom_x1, zoom_x2 = -13.70, -13.35
zoom_y1, zoom_y2 = 3.8, 4.1
# Create new Polygon objects for the inset
original_polygon_inset = Polygon(original_polygon.get_xy(), closed=True, fill=None, edgecolor='blue')
smoothed_polygon_inset = Polygon(smoothed_polygon.get_xy(), closed=True, fill=None, edgecolor='red')
# Create inset of the zoomed region
axins = inset_axes(ax, width="50%", height="50%", loc='center') # Adjust the size and location of the inset
axins.add_patch(original_polygon_inset)
axins.add_patch(smoothed_polygon_inset)
axins.scatter(x_contour, y_contour, s=2, color='blue')
axins.scatter(x_smoothed, y_smoothed, s=2, color='red')
# Set the limits for the zoomed region
axins.set_xlim(zoom_x1, zoom_x2)
axins.set_ylim(zoom_y1, zoom_y2)
axins.set_aspect('equal', 'box')
# Remove axis text annotations from the zoom plot
# axins.set_xticklabels([r'$x$ (m)'])
# axins.set_yticklabels([r'$y$ (m)'])
# Indicate the zoomed region on the main plot
ax.indicate_inset_zoom(axins, edgecolor="black")
mark_inset(ax, axins, loc1=2, loc2=3, fc="none", ec="0.5")
plt.savefig('images/pdf/slab_contour_smoothing.pdf')
plt.show()
def plot_parallel_wall_groups(parallel_groups):
set_plot_style()
fig, ax = plt.subplots(figsize=(8 / 1.2, 5 / 1.2))
num_segments = len(parallel_groups)
random_colors = [np.random.rand(3, ) for _ in range(num_segments)]
for idx, (group, color) in enumerate(zip(parallel_groups, random_colors)):
for seg in group:
ax.plot([seg[0][0], seg[1][0]], [seg[0][1], seg[1][1]], color=color, linewidth=2,
label=f'Group {idx + 1}' if seg is group[0] else "")
ax.set_xlabel(r'$x$ (m)')
ax.set_ylabel(r'$y$ (m)')
fig.tight_layout()
plt.savefig('images/pdf/parallel_wall_groups.pdf')
plt.show()
def plot_segments_with_candidates(facade_wall_candidates):
set_plot_style()
"""Plot facade wall candidates as distinct segments."""
fig, ax = plt.subplots(figsize=(8/1.2, 6/1.2))
# Define a distinct color for facade wall candidates
color = 'grey'
# Plot each segment in facade wall candidates
for seg in facade_wall_candidates:
ax.plot([seg[0][0], seg[1][0]], [seg[0][1], seg[1][1]], color=color, linewidth=2, label='Facade Wall Candidate')
ax.set_title('Visualization of Facade Wall Candidates')
ax.set_xlabel(r'$x$ (m)')
ax.set_ylabel(r'$z$ (m)')
ax.grid(False)
plt.show()
def plot_point_cloud_data(points_xyz, n_points_array, z_array, max_n_points_array, z_step):
set_plot_style()
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12/1.5, 6/1.5)) # 2 plots horizontally
# Convert n_points_array to a numpy array for safe operations
n_points_array = np.array(n_points_array)
# First plot: Histogram of point counts vs z-coordinate
ax1.plot(n_points_array / 1000, z_array, '-r', linewidth=0.8)
ax1.plot([max_n_points_array / 1000, max_n_points_array / 1000], [min(z_array), max(z_array)], '--b', linewidth=1.0)
ax1.set_ylabel(r'$z$ (m)')
ax1.set_xlabel('Number of points ($\\times 10^3$)')
# Determine horizontal surface candidates based on point counts
h_surf_candidates = [(z, z + z_step) for z, n in zip(z_array, n_points_array) if n > max_n_points_array]
# Second plot: Scatter plot for X-Z plane view of all point cloud data
downsampled_indices = np.arange(0, len(points_xyz), 100)
downsampled_points = points_xyz[downsampled_indices]
colors = ['orange' if any(lower - z_step <= z <= upper + z_step for (lower, upper) in h_surf_candidates) else 'blue'
for z in downsampled_points[:, 2]]
ax2.scatter(downsampled_points[:, 1], downsampled_points[:, 2], c=colors, marker='.', alpha=1, s=0.2)
ax2.set_xlabel(r'$x$ (m)')
ax2.set_ylabel(r'$z$ (m)')
ax2.grid(False)
# Set the same y-axis limits for both subplots based on the min and max of z_array
common_z_limit = [min(z_array), max(z_array)]
ax1.set_ylim(common_z_limit)
ax2.set_ylim(common_z_limit)
plt.tight_layout() # Adjust the layout to make sure there is no overlap
plt.savefig('images/pdf/slab_histogram.pdf')
plt.show()
def plot_horizontal_surfaces(horiz_surface_planes):
set_plot_style()
tick_interval = 5 # Interval for major ticks on the axes
# Create a figure and subplots
fig, axs = plt.subplots(1, 2, figsize=(12/1.5, 6/1.5))
axs[0].xaxis.set_major_locator(MultipleLocator(tick_interval))
axs[0].yaxis.set_major_locator(MultipleLocator(tick_interval))
axs[1].xaxis.set_major_locator(MultipleLocator(tick_interval))
axs[1].yaxis.set_major_locator(MultipleLocator(tick_interval))
# Define colors for each surface
colors = ['orange', 'blue', 'green', 'red', 'purple', 'brown', 'pink', 'gray']
# Plot each horizontal surface
for i, surface in enumerate(horiz_surface_planes):
# Random subsampling - taking every 20th point
subsampled_surface = surface[::70]
axs[i].scatter(subsampled_surface[:, 0], subsampled_surface[:, 1], s=0.1, color=colors[i])
axs[i].set_xlabel(r'$x$ (m)')
axs[i].set_ylabel(r'$y$ (m)')
# Show the plot
plt.tight_layout()
plt.savefig('images/pdf/horiz_surf_difference.pdf')
plt.show()
def plot_2d_histogram(mask, x_edges, y_edges):
set_plot_style()
fig = plt.figure(figsize=(8/1.2, 6/1.2))
plt.imshow(mask, extent=[x_edges.min(), x_edges.max(), y_edges.min(), y_edges.max()], cmap='jet',
origin='lower')
plt.colorbar(label='Relative point cloud density', shrink=0.63)
plt.xlabel(r'$x$ (m)')
plt.ylabel(r'$y$ (m)')
plt.grid(False)
fig.tight_layout()
fig.savefig('images/pdf/2d_histogram.pdf', bbox_inches='tight')
fig.show()
def plot_shifted_mask(shifted_mask, x_edges, y_edges):
set_plot_style()
plt.figure(figsize=(8/1.2, 6/1.2))
plt.imshow(shifted_mask, extent=[x_edges.min(), x_edges.max(), y_edges.min(), y_edges.max()], cmap='binary',
origin='lower')
plt.xlabel(r'$x$ (m)')
plt.ylabel(r'$y$ (m)')
plt.title('Binarized mask - shifted')
plt.grid(False)
plt.savefig('images/pdf/slab_mask_binarized.pdf')
plt.show()
def plot_wall(wall_points, thickness, wall_number):
"""Visualize a wall using both 2D and 3D scatter plots as sub-figures within a single figure."""
# Create a single figure with two subplots
fig = plt.figure(figsize=(15, 7))
# 2D Plot (subplot 1)
ax2d = fig.add_subplot(121) # 1 row, 2 columns, plot 1
xs, ys, zs = zip(*wall_points)
ax2d.scatter(xs, zs, c='b', marker='o', s=1)
ax2d.set_aspect('equal', 'box') # Equal aspect ratio
ax2d.text(0.05, 0.95, f'Thickness: {thickness:.3f} m', transform=ax2d.transAxes,
verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.8))
ax2d.set_xlabel('x-coordinate (m)')
ax2d.set_ylabel('z-coordiante (m)')
# 3D Plot (subplot 2)
ax3d = fig.add_subplot(122, projection='3d') # 1 row, 2 columns, plot 2
ax3d.scatter(xs, ys, zs, c='b', marker='o', s=1)
ax3d.set_xlabel('x-coordinate (m)')
ax3d.set_ylabel('y-coordinate (m)')
ax3d.set_zlabel('z-coordinate (m)')
plt.tight_layout()
plt.savefig('images/wall_outputs_images/wall_%d_2D_3D.jpg' % wall_number, dpi=300)
plt.savefig('images/wall_outputs_images/wall_%d_2D_3D.pdf' % wall_number)
plt.show()