Issue
Is it possible to have Altair or Vega(-Lite) render to a PyQt widget, similar to Matplotlib supporting multiple backends? I know I can use a Qt WebView widget to render a web page with Vega-embed, but I want to prevent the overhead of having to serve this, even if locally.
Solution
The best option to visualize a plot with Altair is to use QWebEngineView since altair what is to create javascript code based on the instructions you set. IMHO the best solution is to obtain the html of the chart and set it in a QWebEngineView. In the following example I show how to do the above, in addition to enabling the characteristics of saving the image as svg or png, etc.
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_())
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.