Как изменить оси QChart в PyQt?

В главном окне моего приложения PyQt у меня есть QChartView.

В определенный момент я собираю температуру определенных изображений и группирую их в массивы (средняя, ​​минимальная и максимальная температуры). Моя цель — показать это на линейной диаграмме. Я создал метод, который создает объект QChart и заполняет его необходимыми элементами (осью, QLineSeries, легендой...), а затем устанавливает это в QChartView.

Вот код для создания QChart:

    def loadChart(self):
        self.series_average = QLineSeries()
        self.series_max = QLineSeries()
        self.series_min = QLineSeries()

        self.loadSerie_average()
        self.loadSerie_max()
        self.loadSerie_min()
    
        chart = QChart()
        chart.legend().setVisible(True)
        chart.addSeries(self.series_average)
        chart.addSeries(self.series_max)
        chart.addSeries(self.series_min)
        chart.createDefaultAxes()
    
        self.chartView.setChart(chart)

Вот методы, которые я использую для заполнения QLineSeries значениями из массивов температуры:

def loadSerie_average(self):
    for index, element in enumerate(self.array_average):
        image_num = index + 1  
        self.series_average.append(image_num, element)
    self.series_average.setName('Temperatura Média')

def loadSerie_max(self):
    for index, element in enumerate(self.array_max):
        image_num = index + 1
        self.series_max.append(image_num, element)
    self.series_max.setName('Temperatura Máxima')

def loadSerie_min(self):
    for index, element in enumerate(self.array_min):
        image_num = index + 1
        self.series_min.append(image_num, element)
    self.series_min.setName('Temperatura Minima')  

Вот текущий вывод сгенерированной линейной диаграммы.

Проблема в том, что разница между значениями температуры относительно невелика. В этом случае метод createDefaultAxes() создает линейную диаграмму с меньшими интервалами и меньшими делениями. Но это не соответствует моей потребности. Мне нужно, чтобы ось Y шла от 24,0 до 39,0 с интервалом 1,0. Также галочки на оси X должны отображаться целыми числами.

Читая документацию, я обнаружил, что для создания осей с определенными характеристиками необходимо создавать объекты QValueAxis, и я попробовал следующее решение:

 y_axis = QValueAxis()
 y_axis.setRange(24.0, 39.0)
 y_axis.setLabelFormat("%0.2f")
 y_axis.setTickCount(1)
 y_axis.setMinorTickCount(0)
 y_axis.setTitleText("Temperatures")

 x_axis = QValueAxis()
 x_axis.setRange(1, len(self.array_average))
 x_axis.setLabelFormat("%d")
 x_axis.setTickCount(1)
 x_axis.setMinorTickCount(1)
 x_axis.setTitleText("Exams")
    
 chart = QChart()
 chart.legend().setVisible(True)
 chart.addSeries(self.series_average)
 chart.addSeries(self.series_max)
 chart.addSeries(self.series_min)
 # chart.createDefaultAxes()
 chart.addAxis(x_axis, QtCore.Qt.AlignmentFlag.AlignBottom)
 chart.addAxis(y_axis, QtCore.Qt.AlignmentFlag.AlignLeft)
    
 self.chartView.setChart(chart)

Но линейная диаграмма, сгенерированная в конце, осталась неизменной. Можете ли вы помочь мне понять, почему сгенерированная линейная диаграмма не изменяется и как я могу создать линейную диаграмму, которая мне подходит?

Хочется сделать что-то подобное.

Таким образом, представление становится более централизованным. Я думаю, что это больше подходит.

Вы можете воспроизвести проблему с помощью приведенного ниже фрагмента кода. Если вы раскомментируете строку метода createDefaultAxes и запустите ее снова, вы увидите, что строки строк меняются, даже несмотря на то, что значения массива одинаковы.

from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis
import sys

class Ui_MainWindow(QtWidgets.QMainWindow):
 def __init__(self):
    super().__init__()
    self.setWindowTitle("Trouble LineChart")
    self.setGeometry(100,100, 680,500)
    self.array_medias = [28.284563290387887, 28.170853249077403, 28.776281519708895, 29.041099232443074, 29.232627358676552]
    self.array_maximas = [33.4762780011805, 33.4762780011805, 33.61541095358507, 33.929353828043304, 33.929353828043304]
    self.array_minimas = [20.46583000704794, 20.288281209883735, 20.772403295556217, 21.20685421472882, 21.625995561649745]

    self.show()
    self.loadChart()



 def loadChart(self):

    self.series_media = QLineSeries()
    self.series_maxima = QLineSeries()
    self.series_minima = QLineSeries()

    self.loadSerie_media()
    self.loadSerie_maxima()
    self.loadSerie_minima()

    y_axis = QValueAxis()
    y_axis.setRange(24.0, 40.0)
    y_axis.setLabelFormat("%0.1f")
    y_axis.setTickType(QValueAxis.TickType.TicksDynamic)
    y_axis.setTickInterval(0.5)
    y_axis.setTitleText("Temperaturas")

    x_axis = QValueAxis()
    x_axis.setRange(1, len(self.array_medias))
    x_axis.setLabelFormat("%d")
    x_axis.setTickType(QValueAxis.TickType.TicksDynamic)
    x_axis.setTickInterval(1)
    x_axis.setTitleText("Exames")
    
    chart = QChart()
    chart.addAxis(x_axis, QtCore.Qt.AlignmentFlag.AlignBottom)
    chart.addAxis(y_axis, QtCore.Qt.AlignmentFlag.AlignLeft)
    chart.legend().setVisible(True)
    chart.addSeries(self.series_media)
    chart.addSeries(self.series_maxima)
    chart.addSeries(self.series_minima)
    #chart.createDefaultAxes()
    
    self.chartView = QChartView(chart)
    self.chartView.setGeometry(QtCore.QRect(100, 100, 680, 500))
    self.chartView.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing)
    self.setCentralWidget(self.chartView)

def loadSerie_media(self):
    for index, element in enumerate(self.array_medias): 
        image_num = index + 1  
        self.series_media.append(image_num, element)
    self.series_media.setName('Temperatura Média')

def loadSerie_maxima(self):
    for index, element in enumerate(self.array_maximas):
        image_num = index + 1
        self.series_maxima.append(image_num, element)
    self.series_maxima.setName('Temperatura Máxima')

def loadSerie_minima(self):
    for index, element in enumerate(self.array_minimas):
        image_num = index + 1
        self.series_minima.append(image_num, element)
    self.series_minima.setName('Temperatura Minima')  

App = QtWidgets.QApplication(sys.argv)
window = Ui_MainWindow()
sys.exit(App.exec())
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
0
0
38
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны установить для свойства tickType QValueAxis значение TicksDynamic, а для свойства tickInterval:

y_axis = QValueAxis()
y_axis.setRange(24.0, 39.0)
y_axis.setLabelFormat("%0.2f")
y_axis.setTickType(QValueAxis.TickType.TicksDynamic)
y_axis.setTickInterval(1)
y_axis.setTitleText("Temperatures")

x_axis = QValueAxis()
x_axis.setRange(1, self.series_average.count())
x_axis.setLabelFormat("%d")
y_axis.setTickType(QValueAxis.TickType.TicksDynamic)
y_axis.setTickInterval(1)
x_axis.setTitleText("Exams")

enter image description here

Обновлять

Вы должны прикрепить оси к ряду:

chart.addSeries(self.series_media)
chart.addSeries(self.series_maxima)
chart.addSeries(self.series_minima)

for series in chart.series():
    series.attachAxis(x_axis)
    series.attachAxis(y_axis)

С другой стороны, enumerate имеет параметр, который может изменить начало:

for index, element in enumerate(self.array_medias, start=1):
    self.series_media.append(index, element)

Вы также должны изменить диапазон, поскольку значение не подходит:

y_axis.setRange(20.0, 40.0)

enter image description here

На самом деле теперь оси правильные. Но по какой-то причине я не понимаю, что использование этого метода теперь приводит к тому, что линейные ряды полностью смещаются. После вашего предложения я опубликую ответ, показывающий, как выглядит диаграмма с использованием тех же массивов.

Pedro D. SOuza 16.05.2022 21:47

@PedroD.SOuza 1. Это не ответ, поэтому вы не должны публиковать его в разделе ответов. 2. Я не могу ничего указать, так как не могу воспроизвести проблему. Если вам нужна дополнительная помощь, предоставьте минимальный воспроизводимый пример, также прочитайте Как спросить и Как ответить.

eyllanesc 17.05.2022 03:54

Ой, извини. И спасибо за информацию. Я удалил неправильный ответ. Вот воспроизводимый пример с проблемой. Обратите внимание, что если вы просто раскомментируете строку метода createDefaultAxes, строки будут меняться, даже если значения не изменятся.

Pedro D. SOuza 17.05.2022 05:42

@PedroD.SOuza В SO соответствующая информация не должна зависеть от внешнего ресурса (например, gist), она должна быть в вашем сообщении, поэтому отредактируйте свое сообщение и добавьте туда MRE. Пожалуйста, прочтите правила.

eyllanesc 17.05.2022 05:51

Верно. Еще раз прошу прощения. Я снова отредактировал пост. Ваше решение сработало отлично! Я не понял, что надо привязывать серию к динамическим осям. Большое спасибо за разъяснение и за пациента.

Pedro D. SOuza 17.05.2022 15:36

Другие вопросы по теме