552day(绘制平行线.html)

本文详细介绍了如何使用HTML5的Canvas API绘制平行线,并探讨了线条宽度、颜色的默认设置及显示效果优化方法。

《2019年4月10日》【连续 552天】

标题:绘制平行线.html;
内容:

 

  /*画平行线*/
    ctx.moveTo(100,100.5);
    ctx.lineTo(300,100.5);

    ctx.moveTo(100,200);
    ctx.lineTo(300,200);

    /*描边*/
    ctx.stroke();


    /*关于线条的问题*/
    /*1.默认的宽度是多少   1px*/
    /*2.默认的颜色是什么   黑色*/
    /*产生原因  对齐的点是线的中心位置  会把线分成两个0.5px 显示的是会不饱和增加宽度*/
    /*解决方案  前后移动0.5px */

 

修改以下代码代码要求为:根据温度数据和坐标数据表格,绘制XY、YZ、XZ、平面的等值线图,时间间隔4小时一次生成一个图,每天一幅的组图,结合各平面生成三维冻结壁演化图,温度数值为0的等温线即为冰柱,冰柱相交为冰墙,在冻结壁云图绘制中去除坐标线框,保留温度图例。原来代码为import pandas as pd import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import matplotlib.colors as mcolors from scipy.interpolate import griddata from scipy.spatial.distance import cdist import trimesh import os from datetime import datetime, timedelta import warnings warnings.filterwarnings('ignore') from mpl_toolkits.mplot3d.art3d import Poly3DCollection from skimage import measure class OptimizedFreezingWallAnalysis: def __init__(self, temp_data_file, coord_data_file, stl_file=None): """初始化冻结壁分析系统""" # 设置中文字体 self.set_chinese_font() # 设置工作目录 self.base_dir = r'C:\Users\Admin\Desktop\工况1温度处理' self.output_dir = os.path.join(self.base_dir, '冻结壁分析结果') os.makedirs(self.output_dir, exist_ok=True) # 构建完整文件路径 temp_data_path = os.path.join(self.base_dir, temp_data_file) coord_data_path = os.path.join(self.base_dir, coord_data_file) # 加载数据 self.load_data(temp_data_path, coord_data_path) # 加载边坡模型(可选) self.slope_mesh = None if stl_file: stl_path = os.path.join(self.base_dir, stl_file) if os.path.exists(stl_path): self.load_slope_model(stl_path) # 预处理数据 self.preprocess_data() # 圆柱体参数 self.cylinder_radius = 0.5 # 圆柱体半径 () self.flattened_ratio = 0.3 # 扁圆柱压缩比例 print(f"冻结壁分析系统初始化完成\n结果保存到: {self.output_dir}") def set_chinese_font(self): """设置中文字体支持""" plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans'] plt.rcParams['axes.unicode_minus'] = False def load_data(self, temp_data_file, coord_data_file): """加载温度和坐标数据""" print("加载数据...") # 加载温度数据 self.temp_df = pd.read_excel(temp_data_file) self.temp_df.columns = ['时间', '测点ID', '温度'] # 加载坐标数据 self.coord_df = pd.read_excel(coord_data_file) self.coord_df.columns = ['测点ID', 'X', 'Y', 'Z'] # 合并数据 self.merged_df = pd.merge(self.temp_df, self.coord_df, on='测点ID') self.merged_df['时间'] = pd.to_datetime(self.merged_df['时间']) print(f"加载数据: {len(self.merged_df)}条记录, {len(self.coord_df)}个测点") def load_slope_model(self, stl_file): """加载边坡三维模型""" print(f"加载STL模型: {stl_file}") try: self.slope_mesh = trimesh.load_mesh(stl_file) print(f"加载成功: {len(self.slope_mesh.vertices)}顶点, {len(self.slope_mesh.faces)}面") except Exception as e: print(f"STL加载失败: {e}") def preprocess_data(self): """数据预处理""" # 提取唯一日期和时间 self.merged_df['日期'] = self.merged_df['时间'].dt.date self.merged_df['小时'] = self.merged_df['时间'].dt.hour self.dates = sorted(self.merged_df['日期'].unique()) # 提取测点信息 self.monitoring_points = self.merged_df[['测点ID', 'X', 'Y', 'Z']].drop_duplicates() # 创建插值网格 min_x, max_x = self.coord_df['X'].min(), self.coord_df['X'].max() min_y, max_y = self.coord_df['Y'].min(), self.coord_df['Y'].max() min_z, max_z = self.coord_df['Z'].min(), self.coord_df['Z'].max() grid_points = 30 self.x_grid = np.linspace(min_x - 10, max_x + 10, grid_points) self.y_grid = np.linspace(min_y - 10, max_y + 10, grid_points) self.z_grid = np.linspace(min_z - 5, max_z + 10, grid_points) self.X_grid, self.Y_grid, self.Z_grid = np.meshgrid( self.x_grid, self.y_grid, self.z_grid, indexing='ij' ) print(f"预处理完成: {len(self.dates)}天数据, 网格分辨率{grid_points}") def plot_temperature_time_series(self): """绘制优化线宽的温度时间序列图 - 线宽缩放到0.25倍""" print("绘制温度时间序列图...") fig, axes = plt.subplots(2, 1, figsize=(15, 12)) point_ids = self.monitoring_points['测点ID'].unique() # 温度时间序列图 - 线宽缩放到0.25倍 for point_id in point_ids: point_data = self.merged_df[self.merged_df['测点ID'] == point_id].sort_values('时间') freeze_mask = point_data['温度'] <= 0 # 使用缩放到0.25倍的线宽 axes[0].plot(point_data['时间'], point_data['温度'], linewidth=0.25, alpha=0.7, label=f'测点{point_id}' if point_id == point_ids[0] else "") if freeze_mask.any(): freeze_times = point_data.loc[freeze_mask, '时间'] freeze_temps = point_data.loc[freeze_mask, '温度'] axes[0].scatter(freeze_times, freeze_temps, color='red', s=10, alpha=0.6) axes[0].axhline(y=0, color='r', linestyle='--', alpha=0.7, label='冻结温度 (0°C)') axes[0].set_title('各测点温度时间序列 (线宽0.25)', fontsize=14) axes[0].legend() axes[0].grid(True, alpha=0.3) # 冻结测点数量时间序列 freeze_counts = [len(self.merged_df[(self.merged_df['日期'] == date) & (self.merged_df['温度'] <= 0)]) for date in self.dates] axes[1].plot(self.dates, freeze_counts, 'bo-', linewidth=1, markersize=3) axes[1].set_title('每日冻结测点数量变化', fontsize=14) axes[1].grid(True, alpha=0.3) plt.tight_layout() plt.savefig(os.path.join(self.output_dir, "优化线宽温度时间序列图.png"), dpi=300) plt.close() print("已保存温度时间序列图") def create_ice_wall_effect(self, ax, freezing_points): """创建冰柱扩散成冰墙的效果""" if len(freezing_points) < 3: return points = freezing_points[['X', 'Y', 'Z']].values temperatures = freezing_points['温度'].values # 创建冰墙表面效果 try: # 使用凸包算法创建冰墙表面 from scipy.spatial import ConvexHull if len(points) >= 4: hull = ConvexHull(points[:, :2]) # 只在XY平面创建凸包 # 为每个凸包顶点添加高度信息 for simplex in hull.simplices: # 创建冰墙多边形 vertices = [] for idx in simplex: point = points[idx] # 创建从地面到测点高度的冰柱 base_point = [point[0], point[1], points[:, 2].min()] vertices.append([point[0], point[1], point[2]]) vertices.append([base_point[0], base_point[1], base_point[2]]) if len(vertices) >= 3: # 创建半透明的冰面 poly = Poly3DCollection([vertices], alpha=0.3, facecolor='lightblue', edgecolor='blue', linewidth=0.5) ax.add_collection3d(poly) except Exception as e: print(f"冰墙效果创建失败: {e}") def generate_freezing_cloud_series(self): """生成4小时间隔冻结壁云图序列 - 修改为4小时间隔""" print("生成4小时间隔冻结壁云图序列...") # 确定冻结时间范围 freeze_mask = self.merged_df['温度'] <= 0 if not freeze_mask.any(): print("未检测到冻结数据") return start_time = self.merged_df.loc[freeze_mask, '时间'].min() end_time = self.merged_df.loc[freeze_mask, '时间'].max() # 生成4小时间隔的时间点 - 修改为4小时 current_time = start_time time_points = [] while current_time <= end_time: time_points.append(current_time) current_time += timedelta(hours=4) # 改为4小时 # 按天分组 daily_groups = {} for t in time_points: day = t.date() daily_groups.setdefault(day, []).append(t) # 生成每日组图 for day, times in daily_groups.items(): fig = plt.figure(figsize=(20, 12)) fig.suptitle(f'冻结壁演化 - {day}', fontsize=16) plot_count = min(len(times), 6) # 最多6个子图 for i, t in enumerate(times[:plot_count], 1): ax = fig.add_subplot(2, 3, i, projection='3d') self.plot_optimized_cloud(ax, t) # 使用优化后的云图绘制方法 plt.tight_layout(rect=[0, 0, 1, 0.95]) plt.savefig(os.path.join(self.output_dir, f"冻结壁组图_{day.strftime('%Y%m%d')}.png"), dpi=300, bbox_inches='tight') plt.close() print(f"已保存{day}冻结壁组图") def plot_optimized_cloud(self, ax, time_point): """优化后的冻结壁云图绘制 - 去除坐标线框,保留温度图例""" # 获取当前时间点数据 time_mask = (self.merged_df['时间'] >= time_point - timedelta(minutes=30)) & \ (self.merged_df['时间'] <= time_point + timedelta(minutes=30)) time_data = self.merged_df[time_mask] if time_data.empty: return # 分离冻结和非冻结点 freezing_points = time_data[time_data['温度'] <= 0] non_freezing_points = time_data[time_data['温度'] > 0] # 绘制非冻结测点 - 保留温度图例 scatter_plot = None if not non_freezing_points.empty: scatter_plot = ax.scatter(non_freezing_points['X'], non_freezing_points['Y'], non_freezing_points['Z'], c=non_freezing_points['温度'], cmap='coolwarm', s=30, alpha=0.8, vmin=-20, vmax=20) # 设置固定的温度范围 # 绘制冻结测点 - 冰柱效果 if not freezing_points.empty: # 使用不同的颜色和形状表示冻结程度 ax.scatter(freezing_points['X'], freezing_points['Y'], freezing_points['Z'], c='darkblue', s=80, marker='^', alpha=0.9, label='冻结测点') # 创建冰墙扩散效果 self.create_ice_wall_effect(ax, freezing_points) # 绘制从地面到冻结点的冰柱 min_z = time_data['Z'].min() for _, point in freezing_points.iterrows(): ax.plot([point['X'], point['X']], [point['Y'], point['Y']], [min_z, point['Z']], 'b-', alpha=0.3, linewidth=2) # 去除坐标线框 ax.grid(False) ax.xaxis.pane.set_alpha(0) ax.yaxis.pane.set_alpha(0) ax.zaxis.pane.set_alpha(0) ax.xaxis.pane.set_edgecolor('none') ax.yaxis.pane.set_edgecolor('none') ax.zaxis.pane.set_edgecolor('none') # 设置坐标轴标签 ax.set_xlabel('X (mm)') ax.set_ylabel('Y (mm)') ax.set_zlabel('Z (mm)') # 添加温度图例 if scatter_plot is not None: cbar = plt.colorbar(scatter_plot, ax=ax, shrink=0.6, aspect=20) cbar.set_label('温度 (°C)') # 设置子图标题 ax.set_title(f"{time_point.strftime('%Y-%m-%d %H:%M')}\n冻结测点: {len(freezing_points)}", fontsize=10, pad=10) def run_analysis(self): """运行完整分析流程""" print("启动冻结壁分析...") self.plot_temperature_time_series() self.generate_freezing_cloud_series() print("分析完成!") # ========================= 使用示例 ========================= if __name__ == "__main__": analyzer = OptimizedFreezingWallAnalysis( temp_data_file='温度数据.xlsx', coord_data_file='坐标数据.xlsx', stl_file='complex_model.stl' # 可选参数 ) analyzer.run_analysis()
10-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值