Как визуализировать Altair / Vega в виджете PyQt - PullRequest
1 голос
/ 13 февраля 2020

Возможно ли сделать так, чтобы Altair или Vega (-Lite) визуализировали виджет PyQt, аналогично Matplotlib, поддерживающему несколько бэкэндов? Я знаю, что могу использовать виджет Qt WebView для рендеринга веб-страницы с помощью Vega-embed, но я хочу предотвратить накладные расходы, связанные с обслуживанием этого, даже локально.

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Лучший вариант для визуализации графика с помощью Altair - использовать QWebEngineView, поскольку altair создает код javascript на основе заданных вами инструкций. ИМХО, лучшее решение - получить html диаграммы и установить ее в QWebEngineView. В следующем примере я покажу, как это сделать, помимо включения характеристик сохранения изображения в формате svg или png и т. Д. c.

from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets

from io import StringIO


class WebEngineView(QtWebEngineWidgets.QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.page().profile().downloadRequested.connect(self.onDownloadRequested)
        self.windows = []

    @QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
    def onDownloadRequested(self, download):
        if (
            download.state()
            == QtWebEngineWidgets.QWebEngineDownloadItem.DownloadRequested
        ):
            path, _ = QtWidgets.QFileDialog.getSaveFileName(
                self, self.tr("Save as"), download.path()
            )
            if path:
                download.setPath(path)
                download.accept()

    def createWindow(self, type_):
        if type_ == QtWebEngineWidgets.QWebEnginePage.WebBrowserTab:
            window = QtWidgets.QMainWindow(self)
            view = QtWebEngineWidgets.QWebEngineView(window)
            window.resize(640, 480)
            window.setCentralWidget(view)
            window.show()
            return view

    def updateChart(self, chart, **kwargs):
        output = StringIO()
        chart.save(output, "html", **kwargs)
        self.setHtml(output.getvalue())


if __name__ == "__main__":
    import sys

    import altair as alt
    from vega_datasets import data

    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QMainWindow()

    cars = data.cars()

    chart = (
        alt.Chart(cars)
        .mark_bar()
        .encode(x=alt.X("Miles_per_Gallon", bin=True), y="count()",)
        .properties(title="A bar chart")
        .configure_title(anchor="start")
    )

    view = WebEngineView()
    view.updateChart(chart)
    w.setCentralWidget(view)
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec_())
0 голосов
/ 13 февраля 2020

В настоящее время единственным рендерингом для Altair является Vega-Embed, поэтому для рендеринга в виджете PyQt потребуется запустить движок Javascript. Я подозреваю, что Qt WebView, вероятно, является лучшим вариантом.

Если вы в порядке, теряя интерактивность графиков, вы также можете использовать altair_saver в качестве бэкэнда для хранения stati c PNG, SVG или PDF диаграммы и показать ее в QtWidget.

...