【QT】PySide6 数据可视化折线图

news2024/11/18 11:48:32

一、项目介绍

本项目将通过PySide6构建一个可以显示数据折线图的可视化程序,其中,数据来源时美国地质调查局(US Geological Survey)上公开的一小时地震震级数据。

可以通过链接进行下载。


二、实现步骤

本项目的实现步骤可以概括为:

  • 读取数据
  • 数据处理
  • 创建主窗口
  • 添加控件
  • 绘制图形并显示、

预期结果如下图所示:


三、实现

1️⃣ 读取数据

这里我们借助Pandas对CSV文件进行读取。argparse模块主要用于参数控制,具体可见这篇文章。

创建一个新文档main.py,接下来都是一些简单的操作,就不做赘述了。

import argparse
import pandas as pd

def read_data(file):
    return pd.read_csv(file)

if __name__ == '__main__':
    options=argparse.ArgumentParser()
    options.add_argument("-f","--file",type=str,required=True)
    args=options.parse_args()
    data=read_data(args.file)
    print(data)

我们可以通过终端输入python main.py -f "YourPath"来查看数据读取情况。


2️⃣ 数据清洗

我们在这部,需要将数据中的日期转换为Qt类型,并且确保数据的完整性、准确性。

值得注意的是,数据中的日期是UTC标准(如: 2018-12-11T21:14:44,682Z),我们可以比较容易地转换为QDateTime类型。

这个QtDateTime位于QtCore模块,从QtCore中将其导入:

from PySide6.QtCore import QDateTime,QTimeZone

接着,通过QtDateTime().fromString( time , format )进行转换:

def transform_date(utc,timezone=None):
    # 日期转换
    utc_fmt="yyyy-MM-ddTHH:mm:ss.zzzZ"
    new_date=QDateTime().fromString(utc,utc_fmt)
    if timezone:
        new_date.setTimeZone(timezone)
    return new_date

我们对读取数据方法进行一定的修改,首先是移除错误的震级数据:

    data=pd.read_csv(file)
    data=data.drop(data[data['mag']<0].index)
    magnitudes=data['mag']

然后,设置本地的时区:

    # 时区设置
    timezone = QTimeZone(QTimeZone.systemTimeZone()) # "Asia/Shanghai"
    # 时间转换
    times=data['time'].apply(lambda x:transform_date(x,timezone))
    return times,magnitudes

虽然不该在这篇文档中提,但还是提一嘴:

Pandas快速对某一类操作:

Series.apply(lambda x:func(x)) # apply(func)但是如果要输入参数,可以这样写: .apply(lambda x:func(x))

好了,此时我们的read_data方法应该长这样:

def read_data(file):
    # 读取数据
    data=pd.read_csv(file)
    # 处理震级
    data=data.drop(data[data['mag']<0].index)
    magnitudes=data['mag']
    # 时区设置
    timezone = QTimeZone(QTimeZone.systemTimeZone()) # "Asia/Shanghai"
    # 时间转换
    times=data['time'].apply(lambda x:transform_date(x,timezone))
    return times,magnitudes

3️⃣ 创建主窗体

好啦,终于要进入我们的核心啦,这一步我们将创建一个PySide主窗口。

下图是QMainWindow的布局。
![在

image-20221223210213019

在本项目中,我们需要一个“文件”菜单,用来打开文件对话框,和一个“退出”菜单。应用程序启动时,应该要自动加载状态栏。

我们新建一个文件,叫做MainWindow.py

from PySide6.QtCore import Slot
from PySide6.QtGui import QAction,QKeySequence
from PySide6.QtWidgets import QMainWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        pass

让我们的窗体控件继承自QMainWindow。

然后是菜单栏的设置,直接选择获取self.menuBar()即可,通过addMenu(Str)的方式,可以添加选项。

# 设置菜单栏
self.menu=self.menuBar()
# 添加 文件 菜单项
self.file_menu=self.menu.addMenu("文件")

然后我们为菜单栏添加一个退出事件。这个事件可以通过QAction来直接绑定。QAction("Exit",self)表示退出本窗体。

# 退出事件
exit_action=QAction("Exit",self) # 设置名字
exit_action.setShortcut(QKeySequence.Quit) # 设置快捷键
exit_action.triggered.connect(self.close) # 该事件直接与close函数关联

self.file_menu.addAction(exit_action)

再添加状态栏

# 状态栏
self.status=self.statusBar()
self.status.showMessage("Data loaded and plotted")

以及设置窗口尺寸,直接通过self.screen().availableGeometry()方法获取当前可用的窗口大小,我们将主窗体的大小设置为可用窗口大小的(0.8,0.7)。

# 窗口尺寸
geometry=self.screen().availableGeometry()
self.setFixedSize(geometry.width()*0.8,geometry.height()*0.7)

4️⃣ 添加控件

现在,我们需要添加一个表视图,用来显示数据。

我们可以建一个QTableView对象,并将其放置在QHBoxLayout中,并将其作为小部件传递给我们的主窗体。

值得注意的是,QTableView需要一个模型来显示信息。在这种情况下,可以使用QAbstractTableModel实例。

要子类化QAbstractTable,必须重新实现它的抽象方法rowCount()、columnCount()和data()。通过这种方式,可以确保正确地处理数据。此外,重新实现headerData()方法以向视图提供头部信息。

我们再新建一个文件,就叫做TableModel.py好了。

这里我们实现了三个抽象方法。

from PySide6.QtCore import Qt,QAbstractTableModel,QModelIndex
from PySide6.QtGui import QColor

class CustomTableModel(QAbstractTableModel):
    def __init__(self,data=None):
        super(CustomTableModel, self).__init__()
        self.load_data(data)

    def load_data(self,data):
        # 获取UTC日期
        self.input_dates=data[0].values
        # 获取震级
        self.input_magnitudes=data[1].values

        self.column_count=2
        self.row_count=len(self.input_dates)

    def rowCount(self, parent=QModelIndex()):
        # parent需要获取Qt模型索引
        return self.row_count
    def columnCount(self, parent=QModelIndex()):
        # parent需要获取Qt模型索引
        return self.column_count
    def headerData(self,section,orientation,role):
        # 头文件信息
        if role!=Qt.DisplayRole:
            return None
        if orientation==Qt.Horizontal:
            return ("Date","Magnitude")[section]
        else:
            return f"{section}"

    def data(self,index,role=Qt.DisplayRole):
        # 需要实现的抽象方法
        # index是索引位置,role是当前状态
        
        column=index.column() 
        row=index.row()
        
        if role==Qt.DisplayRole:
            # 如果当前在显示
            if column==0:
                # 表示当前的位置为: row,0 理应返回date数据
                # 返回str格式的数据,除了时区 
                date=self.input_dates[row].toPython()
                return str(date)[:-3]
            elif column==1:
                # 返回震级数据
                magnitude=self.input_magnitudes[row]
                return f"{magnitude:.2f}"
            
        elif role==Qt.BackgroundRole:
            # 在背后的话就返回一个颜色
            return QColor(Qt.white)
        elif role==Qt.TextAlignmentRole:
            return Qt.AlignRight
        return None

接着就可以再构建我们自己的小控件啦,新建一个文件,叫做TableWidge,将我们的模型导入:

from PySide6.QtWidgets import (QHBoxLayout,QHeaderView,QSizePolicy,QTableView,QWidget)
from Q003_TableModel import CustomTableModel # 我这里是写作Q003,去掉就行,换成上一个文件的名字

class Widget(QWidget):
    def __init__(self,data):
        super(Widget, self).__init__()

        # 获取TableModel
        self.model=CustomTableModel(data) # 基于TableModel的数据读取

        # 创建表视图
        self.table_view=QTableView()
        self.table_view.setModel(self.model) # 设置模型

        # 设置表视图的标头
        self.horizontal_header=self.table_view.horizontalHeader()
        self.vertical_header=self.table_view.verticalHeader()
        self.horizontal_header.setSectionResizeMode(
            QHeaderView.ResizeToContents
        )# 依据内容自动设置尺寸
        self.vertical_header.setSectionResizeMode(
            QHeaderView.ResizeToContents
        )
        self.horizontal_header.setStretchLastSection(True) # 拉伸部件

        # 设置布局
        self.main_layout=QHBoxLayout()
        size=QSizePolicy(QSizePolicy.Preferred,QSizePolicy.Preferred) # 默认sizeHint()为最优尺寸的策略

        # 水平布局
        size.setHorizontalStretch(1) # 设置水平拉伸因子为1
        self.table_view.setSizePolicy(size) # 对组件应用尺寸策略
        self.main_layout.addWidget(self.table_view) # mainlayout是一个水平布局盒子,将我们的组件加进来

        # 将布局设置到QWidget中
        self.setLayout(self.main_layout) # 最后,将我们的水平盒子设为小组件的布局

QSizePolicy 类是布局属性,描述了水平和垂直大小调整策略,部分参数如下:

参数名作用
Fixedsize固定为Qwidget.sizeHint()
Minimumsize不能小于sizeHint()的大小
Maximumsize不能大于sizeHint()的大小
Preferred最佳size为sizeHint()
ExpandingsizeHint是推荐的size,但尽可能地获取更大的空间
IgnoredsizeHint()被忽略,小部件将尽可能获取空间

这里我们用到了void setHorizontalStretch\setVerticalStretch (int stretchFactor)方法,这个方法是用来设置大小策略的水平/垂直拉伸因子的,范围必须在[0,255]。举个栗子,当有两个部件水平相邻时,左边的部件拉伸系数为2,右边的拉深系数为1,那么将确保左边窗口的大小始终是右边的两倍。

好了,现在我们有一个TableView组件啦,将其加入主窗口。在MainWindow.py文件中添加如下代码:

class MainWindow(QMainWindow):
    def __init__(self,widget):
        super(MainWindow, self).__init__()
        self.setCentralWidget(widget)

main.py中添加:

from resource.OtherSupportPyFile.Q003_DataProcess import MainWindow
# 注意写成自己的路径和文件名
from resource.OtherSupportPyFile.Q003_Table import Widget
# 注意写成自己的路径和文件名
import sys 
from PySide6.QtWidgets import QApplication


if __name__ == '__main__':
    options=argparse.ArgumentParser()
    options.add_argument("-f","--file",type=str,required=True)
    args=options.parse_args()
    data=read_data(args.file)

    # 创建应用程序
    app=QApplication()
    widget=Widget(data)
    window=MainWindow(widget)
    window.show()

    sys.exit(app.exec())

好了,最后的结果如下所示:

image-20221223221445259

5️⃣ 添加并绘制图

有了表后,就要添加图了!我们在之前的TableWidge.py上修改,基于Pyside6.QCharts绘制图形。

首先是导入模块:

from PySide6.QtWidgets import (QHBoxLayout,QHeaderView,QSizePolicy,QTableView,QWidget)
from .Q003_TableModel import CustomTableModel
from PySide6.QtCharts import QChart,QChartView,QLineSeries,QDateTimeAxis,QValueAxis
from PySide6.QtGui import QPainter
from PySide6.QtCore import QDateTime,Qt

添加创建图的方法

# 创建QChart对象
self.chat=QChart()
self.chat.setAnimationOptions(QChart.AllAnimations) # 设置移动动画

# 创建表视图
self.chat_view=QChartView(self.chat)
self.chat_view.setRenderHint(QPainter.Antialiasing) # 抗锯齿

将图设置为右边,且大小是表的四倍

# 右布局
size.setHorizontalStretch(4)
self.chat_view.setSizePolicy(size)
self.main_layout.addWidget(self.chat_view)

我们创建一个添加序列的方法,用来为Chart读取数据~

def add_series(self,name):
    # 创建线序列QLineSeries
    self.series=QLineSeries()
    self.series.setName(name)

    # 填充QLineSeries
    for i in range(self.model.row_count):

        t=self.model.index(i,0).data()
        data_fmt="yyyy-MM-dd HH:mm:ss.zzz"
        x=QDateTime().fromString(t,data_fmt).toSecsSinceEpoch() # 转化为时间戳
        y=float(self.model.index(i,1).data())
        if x>0 and y>0:
            self.series.append(x,y)

    self.chat.addSeries(self.series)

    # 设置图样式
    # 设置x坐标
    self.axis_x=QDateTimeAxis()
    self.axis_x.setTickCount(10) # 设置间隔
    # self.axis_x.setFormat("dd.MM (h:mm)") # 设置时间显示
    self.axis_x.setFormat("MM.dd") # 设置时间显示
    self.axis_x.setTitleText("Date")
    self.chat.addAxis(self.axis_x,Qt.AlignBottom) # 在表格中加入坐标,位置为底部
    self.series.attachAxis(self.axis_x) # 自动让QLineSeries贴附

    # 设置y坐标
    self.axis_y=QValueAxis()
    self.axis_y.setTickCount(10)
    self.axis_y.setLabelFormat("%.2f")
    self.axis_y.setTitleText("Magnitude")
    self.chat.addAxis(self.axis_y,Qt.AlignLeft)
    self.series.attachAxis(self.axis_y)

    # 从Chart上获取颜色,并在QTableView上使用
    color_name=self.series.pen().color().name()
    self.model.color=f"{color_name}"

将其在初始化方法中绑定:

self.add_series("Magnitude")

最终的结果如下!
在这里插入图片描述


完整代码附上:

1️⃣Q003_TableModel.py

from PySide6.QtCore import Qt,QAbstractTableModel,QModelIndex
from PySide6.QtGui import QColor

class CustomTableModel(QAbstractTableModel):
    def __init__(self,data=None):
        super(CustomTableModel, self).__init__()
        self.load_data(data)

    def load_data(self,data):
        # 获取UTC日期
        self.input_dates=data[0].values
        # 获取震级
        self.input_magnitudes=data[1].values

        self.column_count=2
        self.row_count=len(self.input_dates)

    def rowCount(self, parent=QModelIndex()):
        # parent需要获取Qt模型索引
        return self.row_count
    def columnCount(self, parent=QModelIndex()):
        # parent需要获取Qt模型索引
        return self.column_count
    def headerData(self,section,orientation,role):
        # 头文件信息
        if role!=Qt.DisplayRole:
            return None
        if orientation==Qt.Horizontal:
            return ("Date","Magnitude")[section]
        else:
            return f"{section}"

    def data(self,index,role=Qt.DisplayRole):
        # 需要实现的抽象方法
        # index是索引位置,role是当前状态

        column=index.column()
        row=index.row()

        if role==Qt.DisplayRole:
            # 如果当前在显示
            if column==0:
                # 表示当前的位置为: row,0 理应返回date数据
                # 返回str格式的数据,除了时区
                date=self.input_dates[row].toPython()
                return str(date)[:-3]
            elif column==1:
                # 返回震级数据
                magnitude=self.input_magnitudes[row]
                return f"{magnitude:.2f}"

        elif role==Qt.BackgroundRole:
            # 在背后的话就返回一个颜色
            return QColor(Qt.white)
        elif role==Qt.TextAlignmentRole:
            return Qt.AlignRight
        return None

2️⃣ Q003_DataProcess.py

from PySide6.QtGui import QAction,QKeySequence
from PySide6.QtWidgets import QMainWindow

class MainWindow(QMainWindow):
    def __init__(self,widget):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Earquakes Information")
        self.setCentralWidget(widget)

        # 设置菜单栏
        self.menu=self.menuBar()
        # 添加 文件 菜单项
        self.file_menu=self.menu.addMenu("文件")

        # 退出事件
        exit_action = QAction("Exit", self)  # 设置名字
        exit_action.setShortcut(QKeySequence.Quit)  # 设置快捷键
        exit_action.triggered.connect(self.close)  # 该事件直接与close函数关联

        self.file_menu.addAction(exit_action)

        # 状态栏
        self.status=self.statusBar()
        self.status.showMessage("Data loaded and plotted")

        # 窗口尺寸
        geometry=self.screen().availableGeometry()
        self.setFixedSize(geometry.width()*0.8,geometry.height()*0.7)

3️⃣ Q003_Table.py

from PySide6.QtWidgets import (QHBoxLayout,QHeaderView,QSizePolicy,QTableView,QWidget)
from .Q003_TableModel import CustomTableModel
from PySide6.QtCharts import QChart,QChartView,QLineSeries,QDateTimeAxis,QValueAxis
from PySide6.QtGui import QPainter
from PySide6.QtCore import QDateTime,Qt


class Widget(QWidget):
    def __init__(self,data):
        super(Widget, self).__init__()

        # 获取TableModel
        self.model=CustomTableModel(data) # 基于TableModel的数据读取

        # 创建表视图
        self.table_view=QTableView()
        self.table_view.setModel(self.model) # 设置模型

        # 设置表视图的标头
        self.horizontal_header=self.table_view.horizontalHeader()
        self.vertical_header=self.table_view.verticalHeader()
        self.horizontal_header.setSectionResizeMode(
            QHeaderView.ResizeToContents
        )# 依据内容自动设置尺寸
        self.vertical_header.setSectionResizeMode(
            QHeaderView.ResizeToContents
        )
        self.horizontal_header.setStretchLastSection(True) # 拉伸部件

        # 创建QChart对象
        self.chat=QChart()
        self.chat.setAnimationOptions(QChart.AllAnimations) # 设置移动动画
        self.add_series("Magnitude")

        # 创建表视图
        self.chat_view=QChartView(self.chat)
        self.chat_view.setRenderHint(QPainter.Antialiasing) # 抗锯齿


        # 设置布局
        self.main_layout=QHBoxLayout()
        size=QSizePolicy(QSizePolicy.Preferred,QSizePolicy.Preferred) # 默认sizeHint()为最优尺寸的策略

        # 左布局
        size.setHorizontalStretch(1) # 设置水平拉伸因子为1
        self.table_view.setSizePolicy(size) # 对组件应用尺寸策略
        self.main_layout.addWidget(self.table_view) # mainlayout是一个水平布局盒子,将我们的组件加进来

        # 右布局
        size.setHorizontalStretch(4)
        self.chat_view.setSizePolicy(size)
        self.main_layout.addWidget(self.chat_view)

        # 将布局设置到QWidget中
        self.setLayout(self.main_layout) # 最后,将我们的水平盒子设为小组件的布局

    def add_series(self,name):
        # 创建线序列QLineSeries
        self.series=QLineSeries()
        self.series.setName(name)

        # 填充QLineSeries
        for i in range(self.model.row_count):

            t=self.model.index(i,0).data()
            data_fmt="yyyy-MM-dd HH:mm:ss.zzz"
            x=QDateTime().fromString(t,data_fmt).toSecsSinceEpoch() # 转化为时间戳
            y=float(self.model.index(i,1).data())
            if x>0 and y>0:
                self.series.append(x,y)

        self.chat.addSeries(self.series)

        # 设置图样式
        # 设置x坐标
        self.axis_x=QDateTimeAxis()
        self.axis_x.setTickCount(10) # 设置间隔
        # self.axis_x.setFormat("dd.MM (h:mm)") # 设置时间显示
        self.axis_x.setFormat("MM.dd") # 设置时间显示
        self.axis_x.setTitleText("Date")
        self.chat.addAxis(self.axis_x,Qt.AlignBottom) # 在表格中加入坐标,位置为底部
        self.series.attachAxis(self.axis_x) # 自动让QLineSeries贴附

        # 设置y坐标
        self.axis_y=QValueAxis()
        self.axis_y.setTickCount(10)
        self.axis_y.setLabelFormat("%.2f")
        self.axis_y.setTitleText("Magnitude")
        self.chat.addAxis(self.axis_y,Qt.AlignLeft)
        self.series.attachAxis(self.axis_y)

        # 从Chart上获取颜色,并在QTableView上使用
        color_name=self.series.pen().color().name()
        self.model.color=f"{color_name}"

4️⃣ Main.py

import argparse
import pandas as pd
from PySide6.QtCore import QDateTime,QTimeZone
from PySide6.QtWidgets import QApplication
from resource.OtherSupportPyFile.Q003_DataProcess import MainWindow
from resource.OtherSupportPyFile.Q003_Table import Widget
import sys


def transform_date(utc,timezone=None):
    # 日期转换
    utc_fmt="yyyy-MM-ddTHH:mm:ss.zzzZ"
    new_date=QDateTime().fromString(utc,utc_fmt)
    if timezone:
        new_date.setTimeZone(timezone)
    return new_date

def read_data(file):
    # 读取数据
    data=pd.read_csv(file)
    # 处理震级
    data=data.drop(data[data['mag']<0].index)
    magnitudes=data['mag']
    # 时区设置
    timezone = QTimeZone(QTimeZone.systemTimeZone()) # "Asia/Shanghai"
    # 时间转换
    times=data['time'].apply(lambda x:transform_date(x,timezone))
    return times,magnitudes


if __name__ == '__main__':
    options=argparse.ArgumentParser()
    options.add_argument("-f","--file",type=str,required=True)
    args=options.parse_args()
    data=read_data(args.file)
    # 创建应用程序
    app=QApplication()
    widget=Widget(data)
    window=MainWindow(widget)
    window.show()

    sys.exit(app.exec())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/111241.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

艾美捷过氧化氢酶检测试剂盒的功能和应用

过氧化氢酶&#xff08;EC 1.11.1.6&#xff1b;2H2O2氧化还原酶&#xff09;是一种普遍存在于大多数需氧细胞中的抗氧化酶。过氧化氢酶&#xff08;CAT&#xff09;参与过氧化氢&#xff08;H2O2&#xff09;的解毒&#xff0c;过氧化氢是一种活性氧&#xff08;ROS&#xff0…

领域首创!合合信息与上海大学联合开启贵州原生态古彝文典籍数字化项目

古彝文传承至今已有数千年历史&#xff0c;是世界上最古老的文字之一。2022年12月21日&#xff0c;合合信息与上海大学社会学院正式签署校企合作协议&#xff0c;双方将合力完成以国家珍贵古籍《西南彝志》为中心的贵州古彝文图像识别及数字化校对项目&#xff08;简称“古彝文…

搜索与图论---最短路

最短路:建图! 源点—起点汇点—终点约定n为点数,m为边数1单源最短路:求一个点到其他所有点的最短路 1.1所有边权都是正数 (1)朴素的Dijkstra算法(On^2) 例题:Dijkstra求最短路 I 代码: #include<iostream> #include<cstring> #

代码随想录算法训练营第42天 | 01背包问题 416. 分割等和子集

01背包问题 由于leetcode上没原题&#xff0c;故参考卡哥意见自己编题记录一下。 一、题干 背包最大重量为4。物品为&#xff1a; 物品名称重量价值011513202430––– 问背包能背的物品最大价值是多少&#xff1f; 二、解法 二维dp&#xff1a; 递推公式&#xff1a;dp[i…

数组方法中会更改原数组,不会更改原数组(详细)

1.不会改变原来数组的有&#xff1a; concat() 连接两个或更多的数组&#xff0c;并返回结果。 如果arr.concat&#xff08;&#xff09;里面不放数组参数&#xff0c;则会浅拷贝arr 如果参数不是数组&#xff0c;它不会递归到嵌套数组参数中 数据类型如字符串&#xff0c;数…

elasticsearch小白入门

一般再项目中都会用到 搜索&#xff0c;如果直接查询数据库&#xff0c;性能会存在瓶颈。 这时&#xff0c;用ES就很好的解决这个问题。 ES组件很多&#xff1a;包括 elasticsearch kibana beats logstash 安装 elasticsearch 下载&#xff1a; Elasticsearch 7.10.2 | El…

SpringBoot项目搭建+登录功能实现(小结)

项目目录 登录功能实现思路 目录 1.pom.xml添加依赖 2.配置application.yml文件 3.sql映射文件配置---UserMapper.xml 4.导入页面资源 5.Springboot启动类的配置 6.编写全局配置类 config->AppConfig 7.创建实体类--数据表对应 8.修改login.html页面 9.编写UserCo…

基于SpringBoot的SSMP整合案例

基于SpringBoot的SSMP整合案例 简介&#xff1a;SSMP(SpringSpringMVCMyBatis)&#xff0c;通过SpringBoot整合SSMP来完成增删改查案例。 功能开发模块 实体类开发————使用Lombok快速制作实体类Dao开发————整合MyBatisPlus&#xff0c;制作数据层测试Service开发——…

如意如意猿如意

如意如意猿如意什么是猿如意猿如意效率工具JSON编辑器jsontojava开发工具ChatGPT推荐指数评分及改进意见UI界面效率工具和开发工具ChatGPT一行代码总结经常听到一句话&#xff1a;如意如意随我心意&#xff0c;作为程序猿&#xff0c;我也想要一个如意&#xff0c;心中默念咒语…

LeetCode-91-解码方法

1、动态规划法 我们可以使用动态规划法来解决本问题。我们利用数组dp[i]dp[i]dp[i]来记录字符串前iii位能够组成的解码方法总数。在设计状态转移方程时&#xff0c;我们需要注意这样子的特殊情况&#xff1a;1、当s[i]s[i]s[i]不为0时&#xff0c;单独一个s[i]s[i]s[i]肯定能够…

PID算法总结-从公式原理到参数整定解析

目录 一、控制系统 1.1控制系统的分类 1.2 性能指标 二、PID算法的起源及特点 三、PID应用 四、PID公式原理 五、PID源码 六、PID整定方法 6.1 经验法 6.2 衰减曲线法 6.3 响应曲线法 参考文献&#xff1a; 一、控制系统 1.1控制系统的分类 分为开环控制、闭环控制和复…

Axios(二)

1.axios的基本使用 <!doctype html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, user-scalableno, initial-scale1.0, maximum-scale1.0, minimum-scale1.…

前端基础_像素的处理

像素的处理 在HTML5中使用canvas API所能够做到的图像处理技术中&#xff0c;还有一个更让人惊讶的技术就是像素处理技术。使用canvas API能够获取图像中的每一个像素&#xff0c;然后得到该像素颜色的rgb值或rgba值。 使用图形上下文对象的getImageData方法来获取图像中的像…

Docker安装Nginx 反向代理服务器

前端代码扔在服务器上怎么运行&#xff0c;首先安装Nginx&#xff0c;这里我用Docker安装Nginx 文章目录一、安装nginx docker镜像1、 获取nginx官方镜像2、查看镜像库3、宿主机创建好要挂载的目录4、启动一个不挂载的容器5、配置文件挂载到宿主机6、停止/删除容器7、查看宿主机…

Kaggle手写识别-卷积神经网络Top6%-代码详解

目录 1. Introduction 简介 2. Data preparation 数据准备 2.1 Load data 加载数据 2.2 Check for null and missing values 检查空值和缺失值 2.3 Normalization 规范化 2.4 Reshape 重塑 2.5 Label encoding 标签编码 2.6 Split training and valdiation set 拆分训…

阳康,但没恢复...

这几天真的是被新冠教育了… 我是上周五就开始有症状了&#xff0c;刚开始因为看了太多小感冒、没流感厉害、几天就康复的言论&#xff0c;我以为应该很快就能好&#xff0c;再加上全过程一直没发烧还暗自窃喜&#xff1a;这玩意不过如此嘛。 没想到病毒很快教我重新做人了&a…

代码随想录训练营第15天

题目&#xff1a;二叉树的最大深度 递归法&#xff1a;后序遍历。具体思想&#xff0c; 终止条件是如果指针指向了空&#xff08;也就是此时是叶子结点&#xff09;&#xff0c;那么返回0。然后根据左右中的递归顺序去调用函数&#xff08;并且保存这次的左右子树的深度&#…

矽昌--Wireless配置简述

Wireless配置简述 1 编译 1.1 首次编译 ​ 如果是第一次编译时就需要添加wifi模块&#xff0c;请检查所需编译版型的配置&#xff0c;配置位于openwrt-18.06/target/linux/siflower/ 文件夹下&#xff0c;例如sf19a28_ac28_fullmask_def.config为ac28版型的配置。 查看配置并…

截至2022年12月共计451个信息安全国家标准汇总

写在前面 早年刚参加信息安全工作更多的学点皮毛技术&#xff0c;到处找安全工具&#xff0c;跟踪poc&#xff0c;拿到一个就全网扫一遍&#xff0c;从来没有想过&#xff0c;系统化的安全工作应该怎样搞?我做的工作在安全体系中处于哪个阶段? 后来有机会做企业安全建设&…

计网第二章.物理层

以下是湖科大计算机网络公开课的笔记&#xff1a; 1. 物理层的基本概念 物理层是解决在各种传输媒体上传输比特0和1的问题。 像用双绞线还是光纤或同轴电缆、接线器形状、尺寸、引脚数目、电压范围、某一电平的电压表示何种意义… 物理层为数据链路层屏蔽了各种传输媒体的差…