Skip to content

Commit

Permalink
保存和加载图形:允许用户保存当前绘制的图形,并在以后加载这些图形。
Browse files Browse the repository at this point in the history
导出图形:提供将图形导出为图片(如 PNG 或 SVG 格式)的功能。
更多数学函数支持:添加对更多数学函数的支持
贝塞尔函数:jn() or yn()
双曲函数: sinh(x), cosh(x), tanh(x), asinh(x), acosh(x), atanh(x)
误差函数: erf(x), erfc(x)
伽马函数: gamma(x)
阶乘函数: factorial(x)
其他: sqrt(x), log(x), exp(x), ln(x), sin(x), cos(x), tan(x), sec(x), csc(x), cot(x)
  • Loading branch information
fzlzjerry committed Oct 29, 2024
1 parent 058f92e commit 8eb99eb
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Ensure the following Python libraries are installed:
- NumPy
- SymPy
- Matplotlib
- scipy

You can install all dependencies at once using the following command:

Expand Down
81 changes: 73 additions & 8 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import semver
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget,
QLabel, QLineEdit, QPushButton, QTextBrowser, QMessageBox, QSizePolicy, QSplitter
QLabel, QLineEdit, QPushButton, QTextBrowser, QMessageBox, QSizePolicy, QSplitter, QFileDialog
)
from PyQt6.QtCore import Qt, QEvent, QThread, pyqtSignal
from PyQt6.QtGui import QWheelEvent, QNativeGestureEvent
Expand All @@ -14,13 +14,15 @@
parse_expr, standard_transformations,
implicit_multiplication_application, convert_xor, implicit_application
)
from sympy.functions.special.bessel import jn, yn
from matplotlib.backends.backend_qtagg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT as NavigationToolbar
)
import matplotlib
import matplotlib.pyplot as plt
from itertools import combinations
from scipy import special

matplotlib.use('QtAgg')

Expand Down Expand Up @@ -110,6 +112,17 @@ def initUI(self):
self.plot_button_2d = QPushButton("Plot 2D Graphs")
self.plot_button_2d.clicked.connect(self.plot_graphs_2d)
upper_layout.addWidget(self.plot_button_2d)
buttons_layout = QHBoxLayout()
self.save_button = QPushButton("Save Graphs")
self.save_button.clicked.connect(self.save_graphs)
buttons_layout.addWidget(self.save_button)
self.load_button = QPushButton("Load Graphs")
self.load_button.clicked.connect(self.load_graphs)
buttons_layout.addWidget(self.load_button)
self.export_button = QPushButton("Export Graph")
self.export_button.clicked.connect(self.export_graph)
buttons_layout.addWidget(self.export_button)
upper_layout.addLayout(buttons_layout)
self.result_browser = QTextBrowser()
upper_layout.addWidget(self.result_browser)
splitter.addWidget(upper_widget)
Expand Down Expand Up @@ -185,22 +198,37 @@ def plot_graphs_2d(self):
self.result_browser.setText("Please enter at least one equation.")
return
x = sp.symbols('x')
allowed_symbols = {'x'}
transformations = standard_transformations + (
implicit_multiplication_application, implicit_application, convert_xor)
local_dict = {
'x': x, 'e': np.e, 'pi': np.pi, 'sin': sp.sin, 'cos': sp.cos, 'tan': sp.tan,
'log': sp.log, 'sqrt': sp.sqrt, 'Abs': sp.Abs, 'exp': sp.exp, 'ln': sp.log
'x': x, 'e': np.e, 'pi': np.pi,
'sin': sp.sin, 'cos': sp.cos, 'tan': sp.tan,
'log': sp.log, 'sqrt': sp.sqrt, 'Abs': sp.Abs,
'exp': sp.exp, 'ln': sp.log,
'sinh': sp.sinh, 'cosh': sp.cosh, 'tanh': sp.tanh,
'asinh': sp.asinh, 'acosh': sp.acosh, 'atanh': sp.atanh,
'sec': sp.sec, 'csc': sp.csc, 'cot': sp.cot,
'factorial': sp.factorial, 'gamma': sp.gamma,
'erf': sp.erf, 'erfc': sp.erfc,
'jn': jn, 'yn': yn
}
fig, self.ax = plt.subplots(figsize=(10, 8))
colors = plt.cm.tab10.colors
self.y_funcs_list = []
self.expr_list = []
self.lines = []
self.modules = {
'sin': np.sin, 'cos': np.cos, 'tan': np.tan, 'log': np.log,
'sqrt': np.sqrt, 'Abs': np.abs, 'exp': np.exp, 'ln': sp.log,
'e': np.e, 'pi': np.pi
'sin': np.sin, 'cos': np.cos, 'tan': np.tan,
'log': np.log, 'sqrt': np.sqrt, 'Abs': np.abs,
'exp': np.exp, 'ln': np.log, 'e': np.e, 'pi': np.pi,
'sinh': np.sinh, 'cosh': np.cosh, 'tanh': np.tanh,
'asinh': np.arcsinh, 'acosh': np.arccosh, 'atanh': np.arctanh,
'sec': lambda x: 1 / np.cos(x),
'csc': lambda x: 1 / np.sin(x),
'cot': lambda x: 1 / np.tan(x),
'factorial': special.factorial, 'gamma': special.gamma,
'erf': special.erf, 'erfc': special.erfc,
'jn': special.jn, 'yn': special.yn
}
result_text = ""
for idx, equation in enumerate(equations):
Expand Down Expand Up @@ -589,8 +617,45 @@ def pan_wheel(self, delta_x, delta_y, event):
self.canvas.draw_idle()
self.update_plot()

def save_graphs(self):
options = QFileDialog.Option(0)
file_name, _ = QFileDialog.getSaveFileName(self, "Save Graphs", "", "Text Files (*.txt);;All Files (*)", options=options)
if file_name:
try:
equations = self.entry_2d.text()
with open(file_name, 'w') as f:
f.write(equations)
QMessageBox.information(self, "Success", "Graphs saved successfully.")
except Exception as e:
QMessageBox.warning(self, "Error", f"An error occurred while saving graphs: {str(e)}")

def load_graphs(self):
options = QFileDialog.Option(0)
file_name, _ = QFileDialog.getOpenFileName(self, "Load Graphs", "", "Text Files (*.txt);;All Files (*)", options=options)
if file_name:
try:
with open(file_name, 'r') as f:
equations = f.read()
self.entry_2d.setText(equations)
QMessageBox.information(self, "Success", "Graphs loaded successfully.")
except Exception as e:
QMessageBox.warning(self, "Error", f"An error occurred while loading graphs: {str(e)}")

def export_graph(self):
if self.canvas:
options = QFileDialog.Option(0)
file_name, _ = QFileDialog.getSaveFileName(self, "Export Graph", "", "PNG Files (*.png);;SVG Files (*.svg);;All Files (*)", options=options)
if file_name:
try:
self.canvas.figure.savefig(file_name)
QMessageBox.information(self, "Success", "Graph exported successfully.")
except Exception as e:
QMessageBox.warning(self, "Error", f"An error occurred while exporting the graph: {str(e)}")
else:
QMessageBox.warning(self, "Error", "No graph to export.")

if __name__ == '__main__':
app = QApplication(sys.argv)
window = GraphingCalculator()
window.show()
sys.exit(app.exec())
sys.exit(app.exec())
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ semver~=3.0.2
numpy~=2.1.2
sympy~=1.13.3
matplotlib~=3.9.2
PyQt6~=6.7.1
PyQt6~=6.7.1
scipy~=1.14.1

0 comments on commit 8eb99eb

Please sign in to comment.