Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

FigureCanvas Designer #11423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions 68 doc/users/next_whats_new/qt_designer.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Using Matplotlib with QtDesigner
--------------------------------
QtDesigner is a "WYSIWYG" editor for creating Qt user interfaces. In addition
to the widgets packaged in the Qt library, there is support for custom PyQt5
widgets to be made available within this framework as well. The addition of the
``FigureDesignerPlugin`` makes it possible to include a ``FigureCanvasQt``
widget by simply dragging and dropping in the QtDesigner interface. The
generated XML file can then be loaded using ``pyuic`` and populated with data
using standard ``matplotlib`` syntax.

Environment Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~
Before using the ``FigureDesignerPlugin`` you need to make sure you are in a
compatible environment. First off, ``PyQt5`` has the option to be installed
without QtDesigner. Make sure the installation you were using has not excluded
the Designer.

We will also need to set the ``$PYQTDESIGNERPATH`` environment variable to
properly locate our custom widget plugin. This informs the QtDesigner that we
want the ``FigureCanvas`` widget as an option while we are creating our screen.
On Linux this would look like the example below with your own path to the
``matplotlib`` source code substituted in place.

.. code:: bash

export PYQTDESIGNERPATH=$PYQTDESIGNERPATH:/path/to/matplotlib/lib/matplotlib/mpl-data

For more information consult the `official PyQt
<http://pyqt.sourceforge.net/Docs/PyQt5/designer.html#writing-qt-designer-plugins>`_
documentation. If you are unsure where to find the ``mpl-data`` folder you can
refer to the ``matplotlib.rcParams['datapath']``

Usage
~~~~~
The general process for using the ``QtDesigner`` and ``matplotlib`` is
explained below:

1. If your environment is configured correctly you should see the
``FigureCanvasQt`` widget in the left hand column of your QtDesigner
interface. It can now be used as if it were any other widget, place it in
its desired location and give it a meaningful ``objectName`` for reference
later. The code below assumes you called it "example_plot"

2. Once you are done creating your interface in Designer it is time to load our
the ``.ui`` file created and manipulate the ``matplotlib.Figure``. The
simplest way is to use the ``uic`` to load the ``.ui`` file into a custom
widget. This will make our ``FigureCanvasQt`` object we created in Designer
available to us.

.. code:: python

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget

# Create a QWidget to contain our created display
my_widget = QWidget()
# Load the UI we created in Designer
uic.loadUi('path/to/my_file.ui', widget)
# We now access to the Figure we created in Designer
my_widget.example_plot.figure

3. Now use standard ``matplotlib`` syntax to add axes and data to the
``Figure``.

.. code:: python

ax = my_widget.example_plot.figure.add_subplot(1,1,1)
ax.plot([1, 2, 3], [3, 2, 1])
10 changes: 10 additions & 0 deletions 10 lib/matplotlib/backends/backend_qt5agg.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ctypes

from matplotlib.transforms import Bbox
from matplotlib.figure import Figure

from .backend_agg import FigureCanvasAgg
from .backend_qt5 import (
Expand Down Expand Up @@ -88,3 +89,12 @@ def print_figure(self, *args, **kwargs):
@_BackendQT5.export
class _BackendQT5Agg(_BackendQT5):
FigureCanvas = FigureCanvasQTAgg


class _FigureCanvasQTAgg(FigureCanvasQTAgg):
"""Subclass of FigureCanvasQTAgg that accepts a QWidget as its sole arg
"""
def __init__(self, parent):
figure = Figure()
super().__init__(figure)
self.setParent(parent)
4 changes: 2 additions & 2 deletions 4 lib/matplotlib/backends/qt_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@

if QT_API == QT_API_PYQT5:
try:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets, QtDesigner
_getSaveFileName = QtWidgets.QFileDialog.getSaveFileName
except ImportError:
if _fallback_to_qt4:
Expand All @@ -148,7 +148,7 @@
# needs to be if so we can re-test the value of QT_API which may
# have been changed in the above if block
if QT_API in [QT_API_PYQT, QT_API_PYQTv2]: # PyQt4 API
from PyQt4 import QtCore, QtGui
from PyQt4 import QtCore, QtGui, QtDesigner

try:
if sip.getapi("QString") > 1:
Expand Down
89 changes: 89 additions & 0 deletions 89 lib/matplotlib/mpl-data/figure_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"""
Plugin for drag and drop matplotlib.Figure in QtDesigner
"""
import os.path

import matplotlib
from matplotlib.backends.backend_qt5agg import _FigureCanvasQTAgg
from matplotlib.figure import Figure

# Pyside and Pyside2 do not support the QtDesigner functionality that is
# contained in both PyQt4 and PyQt5. This feature will not be supported with
# those backends until this feature set is available in those libraries
from matplotlib.backends.qt_compat import QtDesigner, QtGui


class FigureDesignerPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin):
"""
QtDesigner Plugin for a matplotlib FigureCanvas

Notes
-----
In order to load this plugin, set the ``PYQTDESIGNERPATH`` environment
variable to the directory that contains this file.
"""
def __init__(self):
QtDesigner.QPyDesignerCustomWidgetPlugin.__init__(self)
self.initialized = False

def initialize(self, core):
"""Mark the QtDesigner plugin as initialized"""
if self.initialized:
return
self.initialized = True

def isInitialized(self):
"""Whether the widget has been initialized"""
return self.initialized

def createWidget(self, parent):
"""Create a FigureCanvasQT instance"""
# Create the Canvas with a new Figure
fig = _FigureCanvasQTAgg(parent)
return fig

def name(self):
"""Name of plugin displayed in QtDesigner"""
return "_FigureCanvasQTAgg"

def group(self):
"""Name of plugin group header in QtDesigner"""
return "Matplotlib Widgets"

def isContainer(self):
"""Whether to allow widgets to be dragged in inside QtCanvas"""
# Someday we may want to set this to True if we can drop in curve
# objects, but this first draft will not include that functionality
return False

def toolTip(self):
"""Short description of Widget"""
return "A matplotlib FigureCanvas"

def whatsThis(self):
"""Long explanation of Widget"""
return self.__doc__

def icon(self):
"""Icon displayed alongside Widget selection"""
mpl_data = os.path.dirname(__file__)
mpl_icon = os.path.join(matplotlib.rcParams['datapath'],
'images', 'matplotlib_large.png')
return QtGui.QIcon(mpl_icon)

def domXml(self):
"""XML Description of the widget's properties"""
return (
"<widget class=\"{0}\" name=\"{0}\">\n"
" <property name=\"toolTip\" >\n"
" <string>{1}</string>\n"
" </property>\n"
" <property name=\"whatsThis\" >\n"
" <string>{2}</string>\n"
" </property>\n"
"</widget>\n"
).format(self.name(), self.toolTip(), self.whatsThis())

def includeFile(self):
"""Include a link to this file for reference"""
return _FigureCanvasQTAgg.__module__
Morty Proxy This is a proxified and sanitized view of the page, visit original site.