如何用Python读取txt坐标数据并实现matplotlib绘图?
搞定你的坐标数据读取与可视化问题
嘿,作为编程新手遇到这种问题太正常了!我来一步步帮你排查问题、实现需求~
一、先把数据读取的坑填上
从你给出的示例x=0 y=3 z=97.72来看,你的txt文件每行是空格分隔的键值对格式,但你代码里用了split(",")按逗号分割,这肯定读不对,这大概率是你读取失败的原因!
我们换个方式提取数值,直接处理每行的键值对:
coordinates = [] with open("example.txt", "r", encoding="ascii") as f: for line in f: # 先去掉换行符,再按空格拆成一个个"x=0"这样的片段 parts = line.strip().split() # 把每个片段按"="拆分,取后面的数值转成对应类型 x = int(parts[0].split("=")[1]) y = int(parts[1].split("=")[1]) z = float(parts[2].split("=")[1]) coordinates.append((x, y, z)) # 打印看看读取结果对不对 print("读取到的坐标:") for p in coordinates: print(p)
如果你的txt是纯逗号分隔的数值(比如每行是0,3,97.72),那只需要修正分割方式,同时注意去掉可能的空格:
coordinates = [] with open("example.txt", "r", encoding="ascii") as f: for line in f: # 先清掉换行和前后空格,再按逗号分割 x_str, y_str, z_str = line.strip().split(",") # 转类型时记得去掉数值前后的空格 x = int(x_str.strip()) y = int(y_str.strip()) z = float(z_str.strip()) coordinates.append((x, y, z))
另外,你后面的遍历代码有两个明显问题:
for x, y in coordinates:会直接报错,因为每个元素是(x,y,z)三元组,得写成for x, y, z in coordinates:x_text、y_text是读取循环里的临时变量,到后面的循环已经失效了,逻辑也没对齐需求,这部分我们后面重新写。
二、随机选两个坐标点
用Python自带的random模块就能轻松实现,记得要选两个不同的点:
import random # 先确保文件里至少有两个点 if len(coordinates) < 2: print("文件里的坐标点不够2个哦!") else: # 随机选两个不重复的点 point1, point2 = random.sample(coordinates, 2) print(f"随机选中的两个点:{point1} 和 {point2}")
三、筛选两个点之间的所有坐标
这里得先明确“二者间的所有坐标”是什么意思,通常有两种常见需求:
需求1:以两个点为对角的矩形区域内的所有点
比如取x的最小到最大值,y的最小到最大值,把这个矩形范围内的点都筛出来:
# 算出矩形的x、y范围 min_x = min(point1[0], point2[0]) max_x = max(point1[0], point2[0]) min_y = min(point1[1], point2[1]) max_y = max(point1[1], point2[1]) # 用列表推导式筛选符合条件的点 filtered_points = [p for p in coordinates if min_x <= p[0] <= max_x and min_y <= p[1] <= max_y] print(f"筛选出的区域内的点:{filtered_points}")
需求2:两点连线上的所有网格点
如果你的x、y是整数网格坐标,想要找两点连线上的点,就得用Bresenham直线算法,不过先默认你需要的是矩形区域的情况,要是需要连线的话可以再调整~
四、用Matplotlib画Z值
我们可以用散点图直观展示每个点的Z值大小,颜色越深代表金额越高:
import matplotlib.pyplot as plt if filtered_points: # 把筛选出的点拆成x、y、z三个列表 xs = [p[0] for p in filtered_points] ys = [p[1] for p in filtered_points] zs = [p[2] for p in filtered_points] # 绘制散点图,用颜色映射Z值 plt.scatter(xs, ys, c=zs, cmap='viridis', s=100) # 加个颜色条说明Z值对应的颜色 plt.colorbar(label='金额值Z') plt.xlabel('X坐标') plt.ylabel('Y坐标') plt.title(f'区域({min_x},{min_y})到({max_x},{max_y})的Z值分布') plt.show() else: print("筛选的区域里没有坐标点哦!")
如果你的坐标是规则网格(每个x、y组合都有对应的Z值),还可以画热力图,看起来更直观:
import numpy as np # 生成一个空网格,大小覆盖筛选的区域 grid = np.zeros((max_y + 1, max_x + 1)) # 把每个点的Z值填到网格对应位置 for p in filtered_points: grid[p[1], p[0]] = p[2] # 绘制热力图 plt.imshow(grid, cmap='viridis', origin='lower') plt.colorbar(label='金额值Z') plt.xlabel('X坐标') plt.ylabel('Y坐标') plt.title('Z值热力图') plt.show()
完整整合代码
把上面的步骤串起来,就是一个能跑通的完整脚本:
import random import matplotlib.pyplot as plt # 1. 读取坐标数据 coordinates = [] try: with open("example.txt", "r", encoding="ascii") as f: for line in f: parts = line.strip().split() x = int(parts[0].split("=")[1]) y = int(parts[1].split("=")[1]) z = float(parts[2].split("=")[1]) coordinates.append((x, y, z)) print(f"成功读取{len(coordinates)}个坐标点") except Exception as e: print(f"读取文件出错啦:{e}") exit() # 2. 随机选取两个点 if len(coordinates) < 2: print("坐标点数量不够,没法选两个点哦") exit() point1, point2 = random.sample(coordinates, 2) print(f"随机选中的点:{point1} 和 {point2}") # 3. 筛选矩形区域内的点 min_x = min(point1[0], point2[0]) max_x = max(point1[0], point2[0]) min_y = min(point1[1], point2[1]) max_y = max(point1[1], point2[1]) filtered_points = [p for p in coordinates if min_x <= p[0] <= max_x and min_y <= p[1] <= max_y] if not filtered_points: print("筛选的区域里没有点哦") exit() # 4. 绘制Z值分布图 xs = [p[0] for p in filtered_points] ys = [p[1] for p in filtered_points] zs = [p[2] for p in filtered_points] plt.scatter(xs, ys, c=zs, cmap='viridis', s=100) plt.colorbar(label='金额值Z') plt.xlabel('X坐标') plt.ylabel('Y坐标') plt.title(f'区域({min_x},{min_y})到({max_x},{max_y})的Z值分布') plt.show()
内容的提问来源于stack exchange,提问作者gregiroir
相关产品推荐
相关产品推荐

