Вопрос или проблема
Я пытаюсь отобразить html-файл plotly в pyside6, но вместо графика plotly у меня получается пустой компонент. Если я пытаюсь открыть сгенерированный файл в веб-браузере, все работает.
import os
import sys
import signal
from PySide6.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWebEngineCore import QWebEngineSettings
from PySide6.QtWebEngineCore import QWebEnginePage
from PySide6.QtCore import QUrl
import plotly.express as px
import pandas as pd
# Пример данных
data = {
'region': ['Алабама', 'Аляска', 'Аризона', 'Арканзас', 'Калифорния'],
'value': [10, 20, 30, 40, 50],
'iso_code': ['US-AL', 'US-AK', 'US-AZ', 'US-AR', 'US-CA']
}
# Создать DataFrame
df = pd.DataFrame(data)
# Создать хлороплетную карту
fig = px.choropleth(
df,
locations="iso_code", # Столбец с кодами регионов (ISO коды)
color="value", # Столбец со значениями для сопоставления интенсивности цвета
locationmode="USA-states", # Указать режим местоположения (например, "USA-states" для США)
scope="usa", # Ограничить область карты
color_continuous_scale="Blues"
)
# Сохранить карту в HTML
html_content = fig.to_html(full_html=True)
# Создать пользовательский класс страницы для перехвата сообщений консоли
class WebEnginePage(QWebEnginePage):
def javaScriptConsoleMessage(self, level, message, lineNumber, sourceID):
print(f"JS Консоль: {message} (Источник: {sourceID}, Строка: {lineNumber})")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# Настроить основной виджет вкладок
self.tab_widget = QTabWidget()
self.setCentralWidget(self.tab_widget)
# Добавить вкладку с хлороплетной картой
self.add_choropleth_tab()
def add_choropleth_tab(self):
# Создать виджет для вкладки
tab = QWidget()
layout = QVBoxLayout()
# Создать QWebEngineView и загрузить HTML-файл
web_view = QWebEngineView()
# Включить JavaScript
web_view.settings().setAttribute(QWebEngineSettings.WebAttribute.JavascriptEnabled, True)
web_view.settings().setAttribute(QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, True)
web_view.settings().setAttribute(QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
html_file_path = os.path.abspath("choropleth_map.html")
local_url = QUrl.fromLocalFile(html_file_path)
web_view.load(local_url)
web_view.setPage(WebEnginePage())
web_view.setHtml(html_content)
layout.addWidget(web_view)
tab.setLayout(layout)
self.tab_widget.addTab(tab, "Хлороплетная карта")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
Ответ или решение
Загрузка графика Plotly в PySide6: Подробное руководство
При использовании библиотеки Plotly для визуализации данных в приложениях на базе PySide6, пользователи часто сталкиваются с проблемой отображения графиков. Один из распространенных случаев — это попытка загрузить HTML-файл, созданный Plotly, внутри компонента QWebEngineView, что иногда приводит к пустому экрану, хотя в браузере график отображается корректно. В этом руководстве мы рассмотрим основные шаги для решения этой проблемы, обеспечивая успешную интеграцию Plotly в ваше PySide6 приложение.
Шаг 1: Установка необходимых библиотек
Прежде всего, убедитесь, что у вас установлены все необходимые библиотеки. Вы можете использовать команду pip для установки PySide6 и Plotly.
pip install PySide6 plotly pandas
Шаг 2: Создание графика
Перед тем как отображать график, вам нужно создать его с помощью Plotly. В вашем коде это делается с помощью библиотеки Plotly Express. Вот пример кода, который создает хоровую карту (choropleth map):
import plotly.express as px
import pandas as pd
# Пример данных
data = {
'region': ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California'],
'value': [10, 20, 30, 40, 50],
'iso_code': ['US-AL', 'US-AK', 'US-AZ', 'US-AR', 'US-CA']
}
# Создание DataFrame
df = pd.DataFrame(data)
# Создание хоровой карты
fig = px.choropleth(
df,
locations="iso_code",
color="value",
locationmode="USA-states",
scope="usa",
color_continuous_scale="Blues"
)
# Сохранение карты в HTML
html_content = fig.to_html(full_html=True)
Шаг 3: Настройка QWebEngineView
Ваша основная задача — корректно инициализировать компонент QWebEngineView для отображения графика. Основное внимание нужно уделить настройкам, связанным с JavaScript и доступом к локальным и удаленным URL:
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtCore import QUrl
# ...
def add_choropleth_tab(self):
# Создание виджета для вкладки
tab = QWidget()
layout = QVBoxLayout()
# Создание QWebEngineView
web_view = QWebEngineView()
# Включение JavaScript
web_view.settings().setAttribute(QWebEngineSettings.WebAttribute.JavascriptEnabled, True)
web_view.settings().setAttribute(QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, True)
web_view.settings().setAttribute(QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
local_url = QUrl.fromLocalFile("path_to_your_html_file.html")
web_view.load(local_url)
# Устанавливаем сгенерированный HTML-код
web_view.setHtml(html_content)
layout.addWidget(web_view)
tab.setLayout(layout)
self.tab_widget.addTab(tab, "Choropleth Map")
Шаг 4: Просмотр и отладка
Убедитесь, что вы правильно указали путь к вашему HTML-файлу и что он действительно существует. Для просмотра сообщений консоли JavaScript, вы можете переопределить метод javaScriptConsoleMessage
в классе WebEnginePage
, что позволит вам видеть потенциальные ошибки:
class WebEnginePage(QWebEnginePage):
def javaScriptConsoleMessage(self, level, message, lineNumber, sourceID):
print(f"JS Console: {message} (Source: {sourceID}, Line: {lineNumber})")
Заключение
Следуя этим шагам, вы сможете успешно загрузить график Plotly в приложение на PySide6. Важно убедиться в правильной настройке QWebEngineView и наличии необходимых библиотек. Не забывайте об отладке и проверке консольных сообщений JavaScript, что поможет выявить и решить возможные проблемы.
Теперь вы готовы интегрировать мощные визуализации данных в свои приложения!