0

I try to plot a chart with dates in the x-axis. But the units displayed are in hours and minutes.

import sys
import datetime
import pyqtgraph as pg
from PySide6.QtWidgets import QApplication, QMainWindow


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

        self.plotWidget = pg.PlotWidget()
        self.setCentralWidget(self.plotWidget)

        self.scatter = pg.ScatterPlotItem()
        self.plotWidget.addItem(self.scatter)
        self.plotWidget.setBackground('w')
        dateAxis = pg.DateAxisItem()
        self.plotWidget.setAxisItems({'bottom': dateAxis})

        self.add_points()

    def add_points(self):
        x_values = [datetime.date(2024, 1, 1), datetime.date(
            2024, 3, 1), datetime.date(2024, 4, 21)]
        points = [
            {'pos': (x_values[0].toordinal(), 1)},
            {'pos': (x_values[1].toordinal(), 2)},
            {'pos': (x_values[2].toordinal(), 3)}]
        self.scatter.addPoints(points)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

enter image description here

How can I force the x-Axis unit with dates? eg 01.01.2024

Thanks for hints

Vik

1 Answer 1

0

This is the best I could get it:

import sys
import datetime
import pyqtgraph as pg
from PySide6.QtWidgets import QApplication, QMainWindow
import time
from collections import OrderedDict


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

        self.plotWidget = pg.PlotWidget()
        self.setCentralWidget(self.plotWidget)

        self.scatter = pg.ScatterPlotItem()
        self.plotWidget.addItem(self.scatter)
        self.plotWidget.setBackground('w')
        dateAxis = pg.DateAxisItem()
        new_zoom_levels = OrderedDict()
        for index, (key, item) in enumerate(dateAxis.zoomLevels.items()):
            if index == 1:
                new_zoom_levels[key*2] = item
            else:
                new_zoom_levels[key] = item

        dateAxis.zoomLevels = new_zoom_levels
        self.plotWidget.setAxisItems({'bottom': dateAxis})

        self.add_points()

    def add_points(self):
        x_values = [datetime.datetime(2024, 1, 1), datetime.datetime(
            2024, 3, 1), datetime.datetime(2024, 4, 21)]
        points = [
            {'pos': (x_values[0].timestamp(), 1)},
            {'pos': (x_values[1].timestamp(), 2)},
            {'pos': (x_values[2].timestamp(), 3)}]
        print(points)
        print(time.time())
        self.scatter.addPoints(points)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
    

The biggest problem in your code is that pyqtgraph expects a unix timestamp, while in your code, an ordinal representation of a date is given (number of days since 1 January 1 AD). This is fixed by changing the datetime.date, to datetime.datetime objects, and then getting the unix timestamp by using .timestamp().

A problem that I ran into, when I did this is that the days where not visible, only the months. I ran into issues with the proper way (using dateAxis.setZoomLevelForDensity()), so I used a bit of a workaround, by adjusting dateAxis.ZoomLevels. If anyone can get the proper way working that would be nice.

Sign up to request clarification or add additional context in comments.

2 Comments

The solution works for me. When one zooms in, the days are shown too. What I don't understand is what the modified new_zoom_levels is for. I played around with it and have problems to understand the effect. Even when I entered an empty new_zoom_levels the results is good. A hint how to get a better understanding would be great. Thanks
@Vik the new_zoom_levels bit is a workaround to get the days to show instead of just the months. In the code for the dateAxis I found ZoomLevels which is a dictionary that defines when to switch to showing months on the x-axis, when days, when hours and so on. This is most definitely not the proper solution, but it's the only thing I could get working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.