You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让坐标绘图脚本支持小数且不触发格式校验错误?

问题与解决方案

问题概述

在Google Colab中实现的笛卡尔平面绘图脚本,支持用逗号分隔坐标(如(x,y), (x,y))连线、点分隔坐标(如(x,y). (x,y))断连,但无法兼容小数坐标——代码会混淆小数点和断连分隔符,且未正确解析浮点数,导致格式错误或无法正常绘图。

修改思路

核心是区分坐标内的小数点和断连用的点符号,同时替换不安全的eval解析方式:

  • 用正则表达式识别断连分隔符:仅匹配)后接.(可带空格)再接(的结构,避免误拆分坐标内的小数点
  • 用正则提取坐标中的数值,显式转换为float类型,确保整数和小数都能正确解析
  • 移除eval,改用更安全的字符串解析逻辑,避免代码注入风险

修改后的完整代码

# Import necessary libraries
import plotly.graph_objects as go
import ipywidgets as widgets
from IPython.display import display, clear_output
import re  # 新增正则模块,用于解析输入

# 解析单个坐标字符串为(float, float)元组
def parse_point(point_str):
    # 匹配(x,y)格式,支持正负整数/小数
    match = re.match(r'\s*\((-?\d+\.?\d*|-?\.\d+)\s*,\s*(-?\d+\.?\d*|-?\.\d+)\)\s*', point_str.strip())
    if not match:
        raise ValueError("Invalid point format")
    x = float(match.group(1))
    y = float(match.group(2))
    return (x, y)

# Function to plot points on a Cartesian plane
def plot_points(points):
    try:
        # 用正则拆分断连的线段:匹配") . ("结构(可带任意空格)
        segment_strings = re.split(r'\)\s*\.\s*\(', points.strip())
        # 处理首尾的括号:第一个 segment 开头可能有(,最后一个可能有)
        segment_strings[0] = segment_strings[0].lstrip('(')
        segment_strings[-1] = segment_strings[-1].rstrip(')')
        
        all_points = []
        segments = []
        # 解析每个线段的坐标
        for seg_str in segment_strings:
            # 拆分当前线段内的所有坐标(逗号分隔)
            point_strings = [s.strip() for s in seg_str.split(',') if s.strip()]
            segment_points = [parse_point(f'({p})') for p in point_strings]
            segments.append(segment_points)
            all_points.extend(segment_points)

        # Extract x and y coordinates from all points
        x_values = [point[0] for point in all_points]
        y_values = [point[1] for point in all_points]

        # Create a new plotly figure
        fig = go.Figure()

        # Add a scatter trace for all points
        fig.add_trace(go.Scatter(x=x_values, y=y_values, mode='markers', name='Points'))

        # Add traces for the lines connecting the points in each segment
        start_idx = 0
        for segment_points in segments:
            num_points = len(segment_points)
            if num_points > 1:  # If segment has more than one point, add line connecting them
                end_idx = start_idx + num_points
                segment_x_values = x_values[start_idx:end_idx]
                segment_y_values = y_values[start_idx:end_idx]
                fig.add_trace(go.Scatter(x=segment_x_values, y=segment_y_values, mode='lines+markers',
                                         line=dict(color='blue', width=2), name=''))
                start_idx = end_idx  # Update start index for the next segment

        # Update layout of the plot
        fig.update_layout(title='Points on Cartesian Plane',
                          xaxis_title='X-Axis', yaxis_title='Y-Axis',
                          xaxis=dict(range=[-99, 99], autorange=False),
                          yaxis=dict(range=[-99, 99], autorange=False, showticklabels=False),
                          showlegend=False,
                          width=600, height=575)

        fig.show()
    except (ValueError, IndexError):
        # Display error message if there's a format error
        error_message.value = "格式错误,请输入正确格式:例如(1.5, 2).(3, 4.2), (5,6)"
        display(error_message)
        display(points_input)
        display(plot_button)

# User input box for points
points_input = widgets.Text(description="坐标:")

# Error message display
error_message = widgets.HTML(value="", layout=widgets.Layout(color='red'))

# Plot button
plot_button = widgets.Button(description="绘图")

def on_plot_button_clicked(b):
    clear_output()
    error_message.value = ""
    plot_points(points_input.value)

plot_button.on_click(on_plot_button_clicked)

# Display the input box and plot button initially
display(points_input)
display(plot_button)

关键修改说明

  • 正则拆分线段:使用re.split(r'\)\s*\.\s*\(', points)精准匹配断连符号,仅当.出现在)和(之间(可带空格)时才作为线段分隔符,避免拆分坐标内的小数点
  • 安全解析坐标:用parse_point函数配合正则提取坐标数值,显式转换为float,支持整数(如(3,4))、正小数((1.5,2))、负小数((-0.5, -3.2))和纯小数((.5, .3))
  • 错误处理优化:捕获ValueError(坐标格式错误)和IndexError(空输入等),给出更清晰的中文提示

内容的提问来源于stack exchange,提问作者Ashton Raymer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 15:14:53