| 1658 | |
| 1659 | |
| 1660 | def plot_bars(self, bar_column, ax): |
| 1661 | if bar_column not in self.data.columns: |
| 1662 | print(f"'{bar_column}' is not a valid column in the data.") |
| 1663 | return |
| 1664 | |
| 1665 | selected_holes_data = self.data[self.data['hole_id'].isin(self.hole_ids)] |
| 1666 | |
| 1667 | # Normalize bar values |
| 1668 | self.bar_vmin = selected_holes_data[bar_column].min() |
| 1669 | self.bar_vmax = selected_holes_data[bar_column].max() |
| 1670 | |
| 1671 | # Compute offset and bar length based on axis limits |
| 1672 | y_min, y_max = ax.get_ylim() |
| 1673 | offset = 0.01 * (y_max - y_min) * self.y_axis_scale_factor |
| 1674 | max_bar_length = 0.05 * (y_max - y_min) * self.y_axis_scale_factor |
| 1675 | |
| 1676 | for hole_id in self.hole_ids: |
| 1677 | hole_data = selected_holes_data[selected_holes_data['hole_id'] == hole_id].sort_values('z') |
| 1678 | if hole_data.empty: |
| 1679 | continue |
| 1680 | |
| 1681 | # Calculate segment ids based on 25m intervals |
| 1682 | hole_data['segment_id'] = (hole_data['z'] // 25).astype(int) |
| 1683 | |
| 1684 | # Calculate a single direction and perpendicular vector per segment |
| 1685 | segment_vectors = {} |
| 1686 | for segment_id in hole_data['segment_id'].unique(): |
| 1687 | segment = hole_data[hole_data['segment_id'] == segment_id] |
| 1688 | start_x, start_y = segment.iloc[0]['x_cross'], segment.iloc[0]['z'] |
| 1689 | end_x, end_y = segment.iloc[-1]['x_cross'], segment.iloc[-1]['z'] |
| 1690 | delta_x, delta_y = end_x - start_x, end_y - start_y |
| 1691 | magnitude = np.sqrt(delta_x**2 + delta_y**2) |
| 1692 | if magnitude == 0: |
| 1693 | continue # Skip segments with no length |
| 1694 | normalized_dir_vector = (delta_x / magnitude, delta_y / magnitude) |
| 1695 | perp_vector = (-normalized_dir_vector[1], normalized_dir_vector[0]) |
| 1696 | |
| 1697 | # Adjust for eastward dipping |
| 1698 | if delta_x < 0: |
| 1699 | perp_vector = (-perp_vector[0], -perp_vector[1]) |
| 1700 | |
| 1701 | # Adjust for vertical or near-vertical holes |
| 1702 | VERTICAL_THRESHOLD = 1 |
| 1703 | if abs(delta_x) < VERTICAL_THRESHOLD: |
| 1704 | perp_vector = (1, 0) # Force bars to the right side |
| 1705 | |
| 1706 | segment_vectors[segment_id] = perp_vector |
| 1707 | |
| 1708 | # Plot bars using the segment's perpendicular vector |
| 1709 | for i, row in hole_data.iterrows(): |
| 1710 | segment_id = row['segment_id'] |
| 1711 | if segment_id not in segment_vectors: |
| 1712 | continue |
| 1713 | perp_vector = segment_vectors[segment_id] |
| 1714 | |
| 1715 | mid_x = row['x_cross'] + perp_vector[0] * offset |
| 1716 | mid_y = row['z'] + perp_vector[1] * offset |
| 1717 | |