Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I embed plotly graphs (offline) in my PyQt4 application?

I know that plotly renders into HTML and can be embedded in web-like environments. I wonder if one can do that inside an HTML window in a PyQt application? Specifically I'd like to know if that works offline, having no internet connection.

EDIT:

This is an excerpt how I finally embedded graphs using matplotlib:

from PyQt4 import QtGui

from matplotlib.backends.backend_qt4agg \
    import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg \
    import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt


class Contour(QtGui.QFrame):

    def __init__(self, parent=None):
        super(Contour, self).__init__(parent)

        self.parent = parent

        # a figure instance to plot on
        self.figure = plt.figure(figsize=(20, 30))
        r, g, b = 100./255., 100./255., 100./255.
        self.figure.patch.set_facecolor(color=(r, g, b))

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)

And then in another function:

    # create an axis
    ax1 = self.figure.add_subplot(211, frame_on=False)
    ax2 = self.figure.add_subplot(212, frame_on=False)

    # plot data
    r, g, b = 39./255., 40./255., 34./255.
    ax1.plot(x, y, ls='o', color=(r, g, b), linewidth=3)
    ax1.plot(coo[0], coo[1], 'go', zorder=20)  # leading edge
    ax1.plot(xg, yg, 'mo', zorder=30)  # leading edge
    ax1.plot(xr, yr, 'yo', zorder=30)  # curvature circle center
    ax1.add_patch(circle)
    ax1.set_title('Contour', fontsize=14)
    ax1.set_xlim(-10.0, 110.0)
    # ax1.set_ylim(-10.0, 14.0)
    r, g, b = 249./255., 38./255., 114./255.
    ax1.fill(x, y, color=(r, g, b))
    ax1.set_aspect('equal')

    ax2.plot(coo[0], gradient, 'go-', linewidth=3)
    ax2.set_title('Gradient', fontsize=14)
    ax2.set_xlim(-10.0, 110.0)
like image 887
chiefenne Avatar asked Mar 07 '15 10:03

chiefenne


People also ask

Does plotly work offline?

Plotly allows you to generate graphs offline and save them in local machine. The plotly. offline. plot() function creates a standalone HTML that is saved locally and opened inside your web browser.

How do you insert a plotly graph into a website?

To share a plot from the Chart Studio Workspace, click 'Share' button on the left-hand side after saving the plot. The Share modal will pop-up and display a link under the 'Embed' tab. You can then copy and paste this link to your website. You have the option of embedding your plot as an HTML snippet or iframe.

Does plotly run locally?

Plotly Offline allows you to create graphs offline and save them locally. Instead of saving the graphs to a server, your data and graphs will remain in your local system.


3 Answers

I once tried using the:

import plotly.offline as plt
.
.
.
plt.plot(fig, filename=testName + '__plot.html')

and then tried to generate a plot.. this gave me an HTML file which then I also tried putting on a QWebView as its URL property [just to see if it renders].

Here is the image for your reference:

Render :: Plotly Offline :: QtWebView

like image 93
mrkrynmdsco Avatar answered Oct 19 '22 02:10

mrkrynmdsco


You can use QWebEngineView from the QWebEngineWidgets module (I used PyQt5 here but I guess it'll also work for PyQt4). You create html code using plotly.offline.plot and set this as the html text for your instance of QWebEngineView. If you specify output_type='div' it will give you directly a string. I do not know why, but in my case it only worked with include_plotlyjs='cdn', but in that case you need to be on the internet for it to work according to the plotly documentation. By doing it that way the plot stays interactive also in your PyQt application.

from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QMainWindow
from plotly.graph_objects import Figure, Scatter
import plotly

import numpy as np


class MainWindow(QMainWindow):

    def __init__(self):

        super(MainWindow, self).__init__()

        # some example data
        x = np.arange(1000)
        y = x**2

        # create the plotly figure
        fig = Figure(Scatter(x=x, y=y))

        # we create html code of the figure
        html = '<html><body>'
        html += plotly.offline.plot(fig, output_type='div', include_plotlyjs='cdn')
        html += '</body></html>'

        # we create an instance of QWebEngineView and set the html code
        plot_widget = QWebEngineView()
        plot_widget.setHtml(html)

        # set the QWebEngineView instance as main widget
        self.setCentralWidget(plot_widget)


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

like image 14
SariO Avatar answered Oct 19 '22 04:10

SariO


Plotly is primarily developed to make graphing in a browser easy. I don't think it can be embedded into a UI framework like PyQT or Tkinter. Plotly has a enterprise version which works in our company network without a internet connection.

PyQtgraph or MatPlotLib may be an option for you if you really need to embedd graphs in PyQT.

Here's sample code to export graphs as png's and then embed png image into your PyQT application.

import matplotlib.pyplot as plt
plt.plot([1,2,3,4,5], [10,20,30])
plt.savefig('graphs.png')

import os,sys
from PyQt4 import QtGui
pic.setPixmap(QtGui.QPixmap("graphs.png"))
like image 2
Phaneendra Avatar answered Oct 19 '22 03:10

Phaneendra