Code Monkey home page Code Monkey logo

Comments (2)

ghtmtt avatar ghtmtt commented on May 29, 2024

Seems not feasible (at least not in a clean way) because the static image relies to the html, hence the browser has to be opened and then the image can be saved. With the QWebView seems not achievable

from dataplotly.

jmonticolo avatar jmonticolo commented on May 29, 2024

Based on your code, I post here a working exporting static image (svg or png) from the QWebview :

import os
import urllib
from base64 import b64decode

import plotly
import plotly.graph_objs as go
from PyQt5.QtCore import QMimeDatabase, pyqtProperty
from PyQt5.QtWebKitWidgets import QWebView

vl = iface.activeLayer()
f1 = [i["PH"] for i in vl.getFeatures()]
f2 = [i["EC"] for i in vl.getFeatures()]
data = [go.Scatter(x=f1, y=f2)]
fig = go.Figure(data=data)

js_func_export = (
    # js function to export image at the webpage size
    # and store graph div id in the gdid variable
    "<script>"
    "function export_img(gd, name, w=null, h=null) {"
    "Plotly.downloadImage(gd, {format: pyObj.fileformat, width: w, height: h, filename: name});};"
    "</script>"
)
# custom buttons in the modeBar to export plot
export_button = (
    "{"
    'name: "Export image",'
    'icon: Plotly.Icons["camera-retro"],'
    "click: function(gd) {export_img(gd)}"
    "}"
)
# create the html DIV
html_plot = js_func_export
html_plot += plotly.offline.plot(
    fig,
    show_link=False,
    validate=True,
    output_type="div",
    image_filename="plot_image",
    image_width=800,
    image_height=600,
    include_mathjax=False,
    config={
        "displaylogo": False,
        "modeBarButtonsToAdd": ["exportButton"],
        "modeBarButtonsToRemove": ["toImage"],
    },
)

html_plot = html_plot.replace('"exportButton"', export_button)


def download_picture(webview, request):
    # avoid "Frame load interrupted by policy change" error
    webview.stop()
    # format default image file name
    image_filename = "my_dataplotly_plot"
    # save image
    request_content = request.url().toString()
    data = request_content.split(",")
    # verify mime type
    mime_type = QMimeDatabase().mimeTypeForFile(request_content).name()
    if mime_type == "application/octet-stream":
        # unquote the mime data
        image = urllib.parse.unquote(data[1])
        svg = image[:4] == "<svg"
        file_format = ["png", "svg"][svg]
        path = QFileDialog.getSaveFileName(
            webview,
            "Save as...",
            f"{os.path.expanduser('~')}/{image_filename}.{file_format}",
            f"Pictures (*.{file_format}",
        )
        # if a save image path is provided
        if path[0] != "":
            if svg:
                # write svg file
                with open(path[0], "w") as file:
                    file.write(image)
            else:
                # decode base 64 png to get the binary data
                png = b64decode(image)
                # write png file
                with open(path[0], "wb") as file:
                    file.write(png)


class PlotImageFormat(QObject):
    def __init__(self, format: str):
        super(PlotImageFormat, self).__init__()
        self._format = format

    def _fileformat(self):
        return self._format

    fileformat = pyqtProperty(str, fget=_fileformat)


wv = QWebView()
wv.setHtml(html_plot)
wv.page().downloadRequested.connect(lambda r: download_picture(wv, r))

pif = PlotImageFormat("svg")
wv.page().mainFrame().addToJavaScriptWindowObject("pyObj", pif)

wv.show()

from dataplotly.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.