数据可视化 第6章



  • 第6章 在图表视图中绘制数据

    1.修改chart_widget.py,添加add_series函数

    from PySide2.QtGui import QPainter
    from PySide2.QtWidgets import (QWidget, QHeaderView, QHBoxLayout, QTableView, QSizePolicy)
    from PySide2.QtCharts import QtCharts
    from PySide2.QtCore import QDateTime
    
    from table_model import *
    
    class Widget(QWidget):
        def __init__(self, data):
            QWidget.__init__(self)
    
            #获取model
            self.model = CustomTableModel(data)
    
            #创建QTableView
            self.table_view = QTableView()
            self.table_view.setModel(self.model)
    
            #QTableView 表头自适应以及拉伸
            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.chart = QtCharts.QChart()
            # 设置全动画模式
            self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations)
            self.add_series("震级", [0, 1])
    
            # 创建 QChartView
            self.chart_view = QtCharts.QChartView(self.chart)
            # 设置抗锯齿
            self.chart_view.setRenderHint(QPainter.Antialiasing)
    
            # 窗口布局
            self.main_layout = QHBoxLayout()
            size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
    
            ## 左侧布局
            size.setHorizontalStretch(1)
            self.table_view.setSizePolicy(size)
            self.main_layout.addWidget(self.table_view)
    
            ## 右侧布局
            size.setHorizontalStretch(4)
            self.chart_view.setSizePolicy(size)
            self.main_layout.addWidget(self.chart_view)
    
            # 窗口添加布局
            self.setLayout(self.main_layout)
    
        def add_series(self, name, columns):
            # 创建QLineSeries
            self.series = QtCharts.QLineSeries()
            self.series.setName(name)
    
            # 将数据放入序列
            for i in range(self.model.rowCount()):
                t = self.model.index(i, 0).data()   #QVariant
                date_fmt = "yyyy-MM-dd HH:mm:ss.zzz"
    
                x = QDateTime().fromString(t, date_fmt).toSecsSinceEpoch()
                y = float(self.model.index(i, 1).data())
                print (i, y)
    
                if x > 0 and y > 0:
                    self.series.append(x, y)
    
            # 添加序列
            self.chart.addSeries(self.series)
    
            # 设置x轴
            self.axis_x = QtCharts.QDateTimeAxis()
            self.axis_x.setTickCount(10)    # 设置要计数的轴上的刻度线数
            self.axis_x.setFormat("dd.MM (h:mm)")
            self.axis_x.setTitleText("日期")
            #
            self.chart.addAxis(self.axis_x, Qt.AlignBottom)
            self.series.attachAxis(self.axis_x)
    
            # 设置y轴
            self.axis_y = QtCharts.QValueAxis()
            self.axis_y.setTickCount(10)    # 设置要计数的轴上的刻度线数
            self.axis_y.setLabelFormat("%.2f")
            self.axis_y.setTitleText("震级")
            #
            self.chart.addAxis(self.axis_y, Qt.AlignLeft)
            self.series.attachAxis(self.axis_y)
    
            # 从QChart获取颜色以在QTableView上使用它,然而并没有使用
            self.model.color = "{}".format(self.series.pen().color().name())
    
    

    2.运行效果,仔细观察,数据是倒着绘制的,即第一条数据在右侧,最后一条数据在左侧
    6.png



  • 为了展示比较漂亮的统计效果图,使用Qt Charts还是很值得的!😀



  • @jiangcaiyang 给你一个大大的赞!
    论坛最近打算再次启用iframely服务了。试试看!

    https://community.nodebb.org/topic/4401


Log in to reply
 

走马观花

最近的回复

  • 113.jpg
    1、什么是lambda表达式,什么是闭包?
    lambda表达式即lambda函数,也就是匿名函数。

    lambda表达式在C++中包含了
    []表示捕获
    ()是函数的参数,需要指定类型
    ->type是返回的类型,可以省略,如果编译器无法推出类型的话可以强制编写
    {}是函数体。

    lambda可以被声明为mutable的,作用是将捕获的内容进行改变。
    闭包是函数的定义以及定义函数时提供的环境,总称为闭包。lambda函数也是一种闭包。
    lambda本身是匿名函数,而捕获语句则是提供了定义函数时提供的环境。

    2、什么是右值引用?
    右值引用相对与左值引用而言的。左值即=运算符左边的变量,右值是=运算符右边的常量或变量。由此可以看出,
    右值引用指的是对常量或变量的引用。它的用途包含了移动语义和完美转发。
    移动语义就是弥补了C++历史在处理变量传递时丢失的一种语义。它和值传递、引用传递一样,是变量传递的方式之一。
    如果没有移动语义,为了将一个类的实例传递给另外一个实例,就需要额外地进行构造、赋值、销毁的操作。
    对于一些比较复杂的变量,的确是非常耗时并且消耗大的操作。(浪费指令时间、浪费内存)

    对于这样的函数返回:
    vector<string> str_split(const string& s) {
    vector<string> v;
    // ...
    return v; // v是左值,但优先移动,不支持移动时仍可复制。
    }

    标准要求先调用移动构造函数,如果不符合那么再调用拷贝构造函数。所以可以轻松地写出这种写法而不必担心效率问题。
    同时,现代编译器都会对返回值进行优化,成为RVO以及NRVO。所以不用太担心会多调用构造析构函数。

    对于完美转发,C++对于引用的转发有规则。传统的C++是无法对引用进行再引用的。但是现代的C++放宽了它的使用范围。
    只有右引用右值的时候,才会产生右引用。这也称为引用折叠。

    3、auto关键字的作用是什么?
    auto关键字为的是能够让编译器自动推导类型。自C++98之后,编译器对类型的推导变得越来越智能了。
    而我们在编写复杂代码的时候,冗长的类型不仅容易出错,有时也不容易人工推导出类型。
    因此auto可以简化我们的任务量,让类型的推导交给编译器完成。
    除了auto外,我们还可以使用decltype()来让编译器推导类型。

    read more
  • 我感觉比起《Physically Based Rendering Technique》,还是《Ray Tracing in a Weekend》更容易上手,因为慢慢地能够做出一个渲染效果,这个是有成就感的。🎓

    read more
  • G

    北京名律免费法律咨询,解决您的法律困扰,如果您眼下没有遇到法律上的问题,也可以留一位大律师的联系方式以备不时之需!ccfd91efc3a6b2ed0e79054d2248eed.jpg bf6015b383483f1fe83cdcfd130fc6b.jpg 2f347879129add1096bf3424edbe517.jpg

    read more

关注我们

微博
QQ群