根据下面代码画出的图,设计路径搜索算法,入口到出口,可视化一条最短路径,并且之能走道路import re
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
def parse_points_from_cell(val):
"""
解析单元格中的{x,y,z}格式数据
val: 单元格内容
返回: 点列表 [(x, y, z), ...]
"""
if pd.isna(val):
return []
s = str(val).strip()
# 尝试多种可能的格式
# 格式1: {x,y,z}
if s.startswith('{') and s.endswith('}'):
s = s[1:-1] # 移除大括号
# 分割字符串
parts = re.split(r'[,\s]+', s)
# 提取数字
numbers = []
for part in parts:
try:
num = float(part)
numbers.append(num)
except ValueError:
continue
points = []
# 每三个数字组成一个点
for i in range(0, len(numbers), 3):
if i + 2 < len(numbers):
x = numbers[i]
y = numbers[i + 1]
z = numbers[i + 2] if i + 2 < len(numbers) else 0.0
points.append((x, y, z))
return points
def visualize_garden_2d(excel_path, sheet_name=0, output_path=None):
"""
可视化花园布局的二维图
excel_path: Excel文件路径
sheet_name: 工作表名称或索引
output_path: 输出图像路径(可选)
"""
try:
# 读取Excel文件(不读取标题行)
print(f"正在读取Excel文件: {excel_path}")
df = pd.read_excel(excel_path, sheet_name=sheet_name, header=None)
print(f"成功读取数据,数据形状: {df.shape}")
print(f"前几行数据:\n{df.head()}")
# 定义类别和对应的颜色(按列顺序)
categories = [
{'name': '道路', 'color': 'gray', 'marker': 's', 'size_scale': 5},
{'name': '半开放建筑', 'color': 'orange', 'marker': '^', 'size_scale': 8},
{'name': '实体建筑', 'color': 'brown', 'marker': 's', 'size_scale': 10},
{'name': '假山', 'color': 'tan', 'marker': 'D', 'size_scale': 12},
{'name': '水体', 'color': 'blue', 'marker': 'o', 'size_scale': 15},
{'name': '植物', 'color': 'green', 'marker': '*', 'size_scale': 6}
]
# 确保类别数量与列数匹配
if len(categories) > df.shape[1]:
categories = categories[:df.shape[1]]
print(f"调整类别数量以匹配列数: {len(categories)}")
# 创建图形
fig, ax = plt.subplots(figsize=(12, 10))
# 为每列数据绘制点
points_found = False
for col_idx in range(min(len(categories), df.shape[1])):
category = categories[col_idx]
print(f"\n处理第{col_idx + 1}列: {category['name']}")
all_points = []
for i, cell in enumerate(df.iloc[:, col_idx]):
points = parse_points_from_cell(cell)
if points:
all_points.extend(points)
if i < 3: # 只打印前几个单元格的解析结果
print(f" 行{i + 1}: '{cell}' -> {points}")
if all_points:
points_found = True
xs, ys, zs = zip(*all_points)
sizes = [max(1, abs(z) * category['size_scale']) for z in zs]
ax.scatter(xs, ys, s=sizes, c=category['color'],
marker=category['marker'], label=category['name'], alpha=0.7)
print(f" 为{category['name']}绘制了{len(all_points)}个点")
else:
print(f" 在{category['name']}中未找到有效点")
# 标记入口和出口
entrance_x, entrance_y = 1.311e5, 4.04e4
exit_x, exit_y = -5.1e3, 2.18e4
# 绘制入口
ax.scatter(entrance_x, entrance_y, s=200, c='red', marker='>',
label='入口', alpha=0.9, edgecolors='black')
ax.annotate('入口', xy=(entrance_x, entrance_y), xytext=(10, 10),
textcoords='offset points', fontsize=12, color='red',
bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="red", alpha=0.7))
# 绘制出口
ax.scatter(exit_x, exit_y, s=200, c='blue', marker='<',
label='出口', alpha=0.9, edgecolors='black')
ax.annotate('出口', xy=(exit_x, exit_y), xytext=(10, 10),
textcoords='offset points', fontsize=12, color='blue',
bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="blue", alpha=0.7))
if not points_found:
print("\n未找到任何有效点,请检查数据格式")
print("数据格式应为 {x,y,z} 或类似格式,例如 '{1,2,3}' 或 '1,2,3'")
# 显示前几行数据以供检查
print("\n前5行数据:")
for i in range(min(5, len(df))):
row_data = []
for j in range(min(7, len(df.columns))):
cell_value = df.iloc[i, j]
row_data.append(f"列{j + 1}: '{cell_value}'")
print(f"行{i + 1}: {', '.join(row_data)}")
return
# 设置图表属性
ax.set_xlabel('X坐标')
ax.set_ylabel('Y坐标')
ax.set_title('花园布局二维可视化(含入口和出口)')
ax.legend(loc='best')
ax.grid(True, linestyle='--', alpha=0.7)
ax.axis('equal') # 保持纵横比一致
# 保存或显示图像
if output_path:
plt.savefig(output_path, dpi=300, bbox_inches='tight')
print(f"\n图像已保存至: {output_path}")
plt.show()
except Exception as e:
print(f"发生错误: {str(e)}")
import traceback
traceback.print_exc()
print("请检查文件路径和格式是否正确")
# 使用示例
if __name__ == "__main__":
excel_file = r"D:\数模01\数模01.xlsx" # 替换为您的实际文件路径
visualize_garden_2d(excel_file, output_path="garden_layout_2d_with_entrance_exit.png")