Python终端Plotter绘图类输出异常 缩放函数故障排查
终端函数绘图功能坐标缩放故障排查
我尝试实现终端函数绘图功能,但当前代码运行后无法输出正确的函数图形。初步判断问题出在scale_to_idx或scale_to_range坐标缩放函数中,但暂未找到修复方法。
该代码预期接收形如x**2的简单函数表达式,根据用户指定的x、y轴取值范围在终端绘制对应函数图像,完整代码如下:
class Plotter(): def __init__(self, size, xrange, yrange): self.size = size self.xrange = xrange self.yrange = yrange self.refresh() def refresh(self): self.pixels = [[" " for i in range(self.size)] for i in range(self.size)] #Draw Left Boundary for y in range(self.size): self.pixels[y][0] = "*" #Draw Bottom Boundary for x in range(self.size): self.pixels[0][x] = '**' def display(self): for row in self.pixels: print("".join(row)) def scale_to_idx(self, value, value_range): ##smth wrong with scale rel = (int(value) - int(value_range[0]))/(int(value_range[0]) - int(value_range[-1])) print("(int(value_range[0]) - int(value_range[-1]))", (int(value_range[0]) - int(value_range[-1]))) print("int(value) - int(value_range[0]))", (int(value) - int(value_range[0]))) idx = rel * self.size return idx def scale_to_range(self, idx, value_range): ##smth wrong with scale rel = idx / self.size value = int(value_range[0]) + rel * (int(value_range[-1]) - int(value_range[0])) return value def plot(self, f, plot_char): for x_idx in range(self.size): x = self.scale_to_range(x_idx, self.xrange) y = f(x_idx) if y > int(self.yrange[0]) or y < int(self.yrange[1]): y_idx = int(self.scale_to_idx(x, self.yrange)) self.pixels[y_idx][x_idx] = plot_char def validate_range(value_range): if len(value_range) != 2: print("Enter two values separated by a space! Try again...") return False if value_range[0] >= value_range[1]: print("Lower end of range must be lower than higher end! Try again...") return False return True if __name__ == "__main__": size = int(input("Enter plot size (Press [ENTER] for default) ") or 50) while True: xrange = input("Enter X-axis range seperated by space (default is '-10 10'): ") or "-10 10" yrange = input("Enter Y-axis range seperated by space (default is '-10 10'): ") or "-10 10" xrange = xrange.split() yrange = yrange.split() if validate_range(xrange) and validate_range(yrange): break plotter = Plotter(size, xrange, yrange) while True: answer = input("Do you wish to add (another) function? [y/n]: ") if answer == "y": func_string = input("Input function code with x as variable (e.g. 'x**2'): ") if not func_string: break plot_char = input("Set Plotting Character: ") or "--" try: exec(f"def f(x): return {func_string}") plotter.plot(f, plot_char) except SyntaxError: print("Invalid Function Expression! Try again...") elif answer == "n": break plotter.display()
已定位的代码错误点
scale_to_idx函数跨度计算符号错误:分母误用value_range[0] - value_range[-1],导致计算出的相对位置为负值,索引完全错位,正确分母应为value_range[-1] - value_range[0]plot方法函数入参错误:计算y值时传入的是像素列索引x_idx,实际应该传入映射到x轴真实取值范围的x变量plot方法范围判断逻辑完全错误:原判断条件y > int(self.yrange[0]) or y < int(self.yrange[1])会放行所有超出y轴范围的点,且逻辑或无法筛选区间内值,正确判断应为y值落在[y轴最小值, y轴最大值]区间内才进行绘制- y轴坐标未做翻转:终端打印顺序是从上到下输出行,对应y轴坐标从最大值递减到最小值,原缩放逻辑直接映射会导致绘制出的函数上下颠倒
- 坐标索引越界风险:原代码没有对计算出的y_idx做边界截断,当y值接近范围边缘时容易出现列表索引超出范围的报错
- 坐标映射基准错误:原缩放逻辑以
self.size为分母计算索引,有效索引范围为0到size-1,会导致最边缘点映射错位
修复后核心逻辑参考
将两个缩放函数和plot方法修改为如下逻辑即可正常绘图:
def scale_to_idx(self, value, value_range): v_min, v_max = int(value_range[0]), int(value_range[1]) # 计算相对位置,截断到[0,1]区间避免越界 rel = max(0, min(1, (value - v_min) / (v_max - v_min))) idx = int(rel * (self.size - 1)) return idx def scale_to_range(self, idx, value_range): v_min, v_max = int(value_range[0]), int(value_range[1]) rel = idx / (self.size - 1) value = v_min + rel * (v_max - v_min) return value def plot(self, f, plot_char): y_min, y_max = int(self.yrange[0]), int(self.yrange[1]) for x_idx in range(self.size): x = self.scale_to_range(x_idx, self.xrange) y = f(x) # 仅绘制y轴范围内的点 if y_min <= y <= y_max: # y轴翻转,适配终端从上到下的打印顺序 y_idx = self.size - 1 - self.scale_to_idx(y, self.yrange) self.pixels[y_idx][x_idx] = plot_char
内容的提问来源于stack exchange,提问作者hihexiy
相关产品推荐
相关产品推荐

