mirror of
https://github.com/goldenfishs/MRobot.git
synced 2026-04-01 05:17:13 +08:00
重构架构
This commit is contained in:
101
app/function_fit_interface.py
Normal file
101
app/function_fit_interface.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QTextEdit, QFileDialog, QLabel
|
||||
from PyQt5.QtCore import Qt
|
||||
from qfluentwidgets import TitleLabel, BodyLabel
|
||||
import pandas as pd
|
||||
import io
|
||||
|
||||
class FunctionFitInterface(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setObjectName("functionFitInterface")
|
||||
|
||||
main_layout = QHBoxLayout(self)
|
||||
main_layout.setContentsMargins(32, 32, 32, 32)
|
||||
main_layout.setSpacing(24)
|
||||
|
||||
# 左侧:数据输入区
|
||||
left_layout = QVBoxLayout()
|
||||
left_layout.setSpacing(16)
|
||||
|
||||
left_layout.addWidget(TitleLabel("数据输入/导入"))
|
||||
self.dataEdit = QTextEdit()
|
||||
self.dataEdit.setPlaceholderText("输入数据,每行格式:x,y")
|
||||
left_layout.addWidget(self.dataEdit)
|
||||
|
||||
btn_layout = QHBoxLayout()
|
||||
import_btn = QPushButton("导入 Excel")
|
||||
import_btn.clicked.connect(self.import_excel)
|
||||
export_btn = QPushButton("导出 Excel")
|
||||
export_btn.clicked.connect(self.export_excel)
|
||||
btn_layout.addWidget(import_btn)
|
||||
btn_layout.addWidget(export_btn)
|
||||
left_layout.addLayout(btn_layout)
|
||||
|
||||
fit_btn = QPushButton("拟合并绘图")
|
||||
fit_btn.clicked.connect(self.fit_and_plot)
|
||||
left_layout.addWidget(fit_btn)
|
||||
|
||||
main_layout.addLayout(left_layout, 1)
|
||||
|
||||
# 右侧:图像展示区
|
||||
right_layout = QVBoxLayout()
|
||||
right_layout.setSpacing(16)
|
||||
right_layout.addWidget(TitleLabel("函数拟合图像"))
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||
|
||||
self.figure, self.ax = plt.subplots()
|
||||
self.canvas = FigureCanvas(self.figure)
|
||||
right_layout.addWidget(self.canvas, stretch=1)
|
||||
|
||||
self.resultLabel = BodyLabel("")
|
||||
right_layout.addWidget(self.resultLabel)
|
||||
|
||||
main_layout.addLayout(right_layout, 2)
|
||||
|
||||
def import_excel(self):
|
||||
path, _ = QFileDialog.getOpenFileName(self, "导入 Excel", "", "Excel Files (*.xlsx *.xls)")
|
||||
if path:
|
||||
df = pd.read_excel(path)
|
||||
text = "\n".join(f"{row[0]},{row[1]}" for row in df.values)
|
||||
self.dataEdit.setText(text)
|
||||
|
||||
def export_excel(self):
|
||||
path, _ = QFileDialog.getSaveFileName(self, "导出 Excel", "", "Excel Files (*.xlsx)")
|
||||
if path:
|
||||
data = self.parse_data()
|
||||
if data is not None:
|
||||
df = pd.DataFrame(data, columns=["x", "y"])
|
||||
df.to_excel(path, index=False)
|
||||
|
||||
def parse_data(self):
|
||||
lines = self.dataEdit.toPlainText().strip().split('\n')
|
||||
data = []
|
||||
for line in lines:
|
||||
try:
|
||||
x, y = map(float, line.split(','))
|
||||
data.append([x, y])
|
||||
except Exception:
|
||||
continue
|
||||
return data if data else None
|
||||
|
||||
def fit_and_plot(self):
|
||||
data = self.parse_data()
|
||||
if not data:
|
||||
self.resultLabel.setText("数据格式错误或为空")
|
||||
return
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
x = np.array([d[0] for d in data])
|
||||
y = np.array([d[1] for d in data])
|
||||
# 简单线性拟合
|
||||
coeffs = np.polyfit(x, y, 1)
|
||||
y_fit = np.polyval(coeffs, x)
|
||||
self.ax.clear()
|
||||
self.ax.scatter(x, y, label="原始数据")
|
||||
self.ax.plot(x, y_fit, color='r', label=f"拟合: y={coeffs[0]:.3f}x+{coeffs[1]:.3f}")
|
||||
self.ax.legend()
|
||||
self.canvas.draw()
|
||||
self.resultLabel.setText(f"拟合公式: y = {coeffs[0]:.3f}x + {coeffs[1]:.3f}")
|
||||
Reference in New Issue
Block a user