I'm trying to display some Plot.ly or Plot.ly Dash plots ( I haven't settled on using one or the other, so I'm experimenting with both right now) in a PyQt5 GUI using QWebEngineView. This doesn't work for any plots larger than 2MB due to some Chromium-level hardcoded restriction.
I found one similar question that is pretty much identical in terms of our needs. It looks like the OP actually found an answer, but unfortunately for me, they didn't post an example of working code or explain what they did to make it work. I do not understand enough of the underlying theory to piece together an answer with the resources linked in this other question, and my Stack reputation isn't high enough to comment and ask the OP what exactly worked.
Here is a minimum reproducible example that displays a plot embedded in the GUI. It's a modification of an answer to a question about embedding Plotly plots in PyQt5 GUIs here:
import numpy as np
import plotly.offline as po
import plotly.graph_objs as go
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
def show_qt(fig):
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
raw_html += '<body>'
raw_html += po.plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
fig_view = QWebEngineView()
# setHtml has a 2MB size limit, need to switch to setUrl on tmp file
# for large figures.
fig_view.setHtml(raw_html)
# fig_view.setUrl(QUrl('temp-plot.html'))
fig_view.show()
fig_view.raise_()
return fig_view
if __name__ == '__main__':
app = QApplication(sys.argv)
# Working small plot:
fig = go.Figure(data=[{'type': 'scattergl', 'y': [2, 1, 3, 1]}])
# Not working large plot:
# t = np.arange(0, 200000, 1)
# y = np.sin(t/20000)
fig = go.Figure(data=[{'type': 'scattergl', 'y': y}])
# po.plot(fig)
fig_view = show_qt(fig)
sys.exit(app.exec_())
Here is a modified version that demonstrates how a large data set cannot be displayed the same way:
import numpy as np
import plotly.offline as po
import plotly.graph_objs as go
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
def show_qt(fig):
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
raw_html += '<body>'
raw_html += po.plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
fig_view = QWebEngineView()
# setHtml has a 2MB size limit, need to switch to setUrl on tmp file
# for large figures.
fig_view.setHtml(raw_html)
# fig_view.setUrl(QUrl('temp-plot.html'))
fig_view.show()
fig_view.raise_()
return fig_view
if __name__ == '__main__':
app = QApplication(sys.argv)
# Working small plot:
# fig = go.Figure(data=[{'type': 'scattergl', 'y': [2, 1, 3, 1]}])
# Not working large plot:
t = np.arange(0, 200000, 1)
y = np.sin(t/20000)
fig = go.Figure(data=[{'type': 'scattergl', 'y': y}])
# po.plot(fig)
fig_view = show_qt(fig)
sys.exit(app.exec_())
Lastly, here is something I tried to get the large plot to display with QUrl pointing to a local html plot on the disk:
import numpy as np
import plotly.offline as po
import plotly.graph_objs as go
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
def show_qt(fig):
raw_html = '<html><head><meta charset="utf-8" />'
raw_html += '<script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head>'
raw_html += '<body>'
raw_html += po.plot(fig, include_plotlyjs=False, output_type='div')
raw_html += '</body></html>'
fig_view = QWebEngineView()
# setHtml has a 2MB size limit, need to switch to setUrl on tmp file
# for large figures.
# fig_view.setHtml(raw_html)
fig_view.setUrl(QUrl('temp-plot.html'))
fig_view.show()
fig_view.raise_()
return fig_view
if __name__ == '__main__':
app = QApplication(sys.argv)
# Working small plot:
# fig = go.Figure(data=[{'type': 'scattergl', 'y': [2, 1, 3, 1]}])
# Not working large plot:
t = np.arange(0, 200000, 1)
y = np.sin(t/20000)
fig = go.Figure(data=[{'type': 'scattergl', 'y': y}])
# po.plot(fig)
fig_view = show_qt(fig)
sys.exit(app.exec_())
The plot was generated with:
import numpy as np
import plotly.offline as po
import plotly.graph_objs as go
t = np.arange(0, 200000, 1)
y = np.sin(t/20000)
fig = go.Figure(data=[{'type': 'scattergl', 'y': y}])
po.plot(fig)