如何明确设置QChart轴刻度?

时间:2017-03-24 17:31:44

标签: qt pyqt

使用Zoom Line Example我创建了一个Python QChartView类,可以使用箭头键滚动并使用加号和减号键进行缩放。 (见下面的代码)。

当我向左滚动时,我希望网格线和轴刻度滚动与数据相同的量。但是,只有数据(QLineSeries)向左滚动。 5个网格线保持在相同的位置,但它们的刻度值会更新。这是不可取的,因为新的刻度值可以是任何值。

我查看了文档,但找不到如何使网格与数据一起滚动。我错过了什么吗?

我还希望能够将刻度设置为显式值(这样我自己也可以实现滚动行为)。是否可以将轴刻度值设置为特定值?

我的示例代码:

import sys
from math import pi, sin, sqrt

from PyQt5.QtChart import QLineSeries, QChart, QChartView
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication

class ZoomPanChartView(QChartView):
    """ QChartView that can zoom/pan with the keys
    """
    def __init__(self, chart):
        super().__init__(chart)

        self.zoomFactor = sqrt(2) # QCharts default is 2
        self.panPixels = 10

    def keyPressEvent(self, keyEvent):
        """ Panning (scrolling) is done with the arrow keys. 
            Zooming goes with the plus and minus keys.
            The '=' key resets.
        """
        key = keyEvent.key()

        if key == Qt.Key_Equal:
            self.chart().zoomReset()
        if key == Qt.Key_Plus:
            self.chart().zoom(self.zoomFactor)
        elif key == Qt.Key_Minus:
            self.chart().zoom(1/self.zoomFactor)
        elif key == Qt.Key_Left:
            self.chart().scroll(-self.panPixels, 0)
        elif key == Qt.Key_Right:
            self.chart().scroll(+self.panPixels, 0)
        elif key == Qt.Key_Up:
            self.chart().scroll(0, +self.panPixels)
        elif key == Qt.Key_Down:
            self.chart().scroll(0, -self.panPixels)
        elif key == Qt.Key_0:
            self.chart().axisX().applyNiceNumbers() # changes the range
        else:
            super().keyPressEvent(keyEvent)


def main():
    app = QApplication(sys.argv)
    chart = QChart()

    series = QLineSeries()
    for i in range(0, 100):
        x = i * pi / 20
        y = sin(x)
        series.append(x, y)

    chart.addSeries(series)
    chart.createDefaultAxes()
    chart.axisY().setRange(-1, 1)
    chart.legend().hide()

    chartView = ZoomPanChartView(chart)
    chartView.show()
    chartView.resize(400, 300)
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()    

2 个答案:

答案 0 :(得分:4)

您可以使用QCategoryAxis将刻度线放在您想要的位置:

初​​始化:

func authorizeBase() {
    let loginString = NSString(format: "%@:%@", username, password)
    let loginData: NSData = loginString.data(using: String.Encoding.utf8.rawValue)! as NSData
    let base64LoginString = loginData.base64EncodedString(options: [])

    let url: NSURL = NSURL(string: urlPath)!

    let request: NSMutableURLRequest = NSMutableURLRequest(url: url as URL)
    request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
    request.httpMethod = "GET"

    let config = URLSessionConfiguration.default

    config.requestCachePolicy = .reloadIgnoringLocalCacheData //deactivate cache
    config.urlCache = nil

    let authString = "Basic \(base64LoginString)"
    config.httpAdditionalHeaders = ["Authorization" : authString]
    let session = URLSession(configuration: config)

    session.dataTask(with: url as URL) {
        ( data, response, error) in
        if (response as? HTTPURLResponse) != nil {
            _ = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)

            let contents = String(data: data!, encoding: .ascii)

            print("apple watch: Content:", contents!)
            self.parseHTMLOverview(content: contents!)

            self.updateTable() //!!!

        }
        else {
            print("apple watch: error with loading nsurlsession")
        }

    }.resume()

}

添加系列:

ch = self.chView.chart()
self.chartAxisX = QCategoryAxis(labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue, startValue=0.0)
ch.setAxisX(self.chartAxisX)
self.chartAxisY = QCategoryAxis(labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue, startValue=0.0)
ch.setAxisY(self.chartAxisY)

将滴答设置为5的倍数:

        ch.addSeries(s)
        s.attachAxis(self.chartAxisX)
        s.attachAxis(self.chartAxisY)

或在任何时间间隔内使用此通用函数:

        for s in self.chartAxisX.categoriesLabels():
            self.chartAxisX.remove(s)
        for i in range(0, int(max_x_value) + 1, 5):
            self.chartAxisX.append(str(i), i)
        self.chartAxisX.setRange(0.0, max_x_value)

答案 1 :(得分:1)

我能找到的最好效果是在QChart上设置QValueAxis作为轴,并调用QValueAxis::applyNiceNumbers()来调整范围,即当前比例的最大值和最小值,以便数字显示的更具人性化。但这将改变数据的位置,而不是网格线的位置。您可以在horizontalBarChart示例中查看函数的行为。

我想过使用QLineSeries数据集来自己创建网格,但是我需要更改轴上的刻度线位置,就我所能确定的那样,当前的QChart不容易。

简短的回答:你不能用QCharts来做..

我已经和Qwt库一起工作了一段时间,我可以证明那里的网格表现得像预期的那样,其他行为也有点成熟。平移可以移动手柄,缩放可以使网格逐步调整大小以保持人类可读性。也许值得一试。