From df4b54c2eb0f26f96a7b710447b60d8664c477df Mon Sep 17 00:00:00 2001 From: Joshua Burnett Date: Tue, 27 Nov 2018 12:34:12 -0500 Subject: [PATCH] Initial commit Initial commit to GitHub --- .gitignore | 3 + MANIFEST.in | 1 + README.md | 23 +++++++ __init__.py | 1 + addcopyfighandler.py | 59 ++++++++++++++++++ build/lib/addcopyfighandler.py | 59 ++++++++++++++++++ ...dcopyfighandler-1.0.1-py2.py3-none-any.whl | Bin 0 -> 2668 bytes dist/addcopyfighandler-1.0.1.tar.gz | Bin 0 -> 2541 bytes generate_source_dist.bat | 1 + setup.py | 55 ++++++++++++++++ 10 files changed, 202 insertions(+) create mode 100644 .gitignore create mode 100644 MANIFEST.in create mode 100644 README.md create mode 100644 __init__.py create mode 100644 addcopyfighandler.py create mode 100644 build/lib/addcopyfighandler.py create mode 100644 dist/addcopyfighandler-1.0.1-py2.py3-none-any.whl create mode 100644 dist/addcopyfighandler-1.0.1.tar.gz create mode 100644 generate_source_dist.bat create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2258b7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +*.egg-info +__pycache__ diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..4bf4483 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include README.md \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..48dc94f --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +addcopyfighandler: Adds a Ctrl+C handler to matplotlib figures for copying the figure to the clipboard +====================================================================================================== + +Simply importing this module (after importing matplotlib) will add a handler +so that pressing Ctrl+C with a matplotlib figure window selected will copy +the figure to the clipboard as an image. + +Original concept code taken from: +https://stackoverflow.com/questions/31607458/how-to-add-clipboard-support-to-matplotlib-figures + + +Releases +-------- + +### 1.0: 2017-08-09 + +- Initial release + + +### 1.0.1: 2018-11-27 + +- Improve setup.py: remove need for importing module, add proper installation dependencies +- Change readme from ReST to Markdown \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..7f96e8c --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +# empty on purpose diff --git a/addcopyfighandler.py b/addcopyfighandler.py new file mode 100644 index 0000000..daf15a5 --- /dev/null +++ b/addcopyfighandler.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +""" +Monkey-patch plt.figure() to support Ctrl+C for copying to clipboard as an image + +@author: Josh Burnett +Modified from code found on Stack Exchange: + https://stackoverflow.com/questions/31607458/how-to-add-clipboard-support-to-matplotlib-figures +""" + + +import matplotlib.pyplot as plt +from win32gui import GetWindowText, GetForegroundWindow + +import io +import qtpy + +__version__ = (1, 0, 1) + +if qtpy.API == 'pyqt4': + from PyQt4.QtGui import QApplication, QImage + clipboard = QApplication.clipboard +elif qtpy.API == 'pyqt5': + from PyQt5.QtGui import QGuiApplication, QImage + clipboard = QGuiApplication.clipboard + +oldfig = plt.figure + + +def copyfig(fig=None): + # store the image in a buffer using savefig(), this has the + # advantage of applying all the default savefig parameters + # such as background color; those would be ignored if you simply + # grab the canvas using Qt + if fig is None: + # find the figure window that has UI focus right now (not necessarily the same as plt.gcf()) + fig_window_text = GetWindowText(GetForegroundWindow()) + for i in plt.get_fignums(): + if plt.figure(i).canvas.get_window_title() == fig_window_text: + fig = plt.figure(i) + break + + buf = io.BytesIO() + fig.savefig(buf) + clipboard().setImage(QImage.fromData(buf.getvalue())) + buf.close() + + +def newfig(*args, **kwargs): + fig = oldfig(*args, **kwargs) + + def clipboard_handler(event): + if event.key == 'ctrl+c': + copyfig() + + fig.canvas.mpl_connect('key_press_event', clipboard_handler) + return fig + + +plt.figure = newfig diff --git a/build/lib/addcopyfighandler.py b/build/lib/addcopyfighandler.py new file mode 100644 index 0000000..daf15a5 --- /dev/null +++ b/build/lib/addcopyfighandler.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +""" +Monkey-patch plt.figure() to support Ctrl+C for copying to clipboard as an image + +@author: Josh Burnett +Modified from code found on Stack Exchange: + https://stackoverflow.com/questions/31607458/how-to-add-clipboard-support-to-matplotlib-figures +""" + + +import matplotlib.pyplot as plt +from win32gui import GetWindowText, GetForegroundWindow + +import io +import qtpy + +__version__ = (1, 0, 1) + +if qtpy.API == 'pyqt4': + from PyQt4.QtGui import QApplication, QImage + clipboard = QApplication.clipboard +elif qtpy.API == 'pyqt5': + from PyQt5.QtGui import QGuiApplication, QImage + clipboard = QGuiApplication.clipboard + +oldfig = plt.figure + + +def copyfig(fig=None): + # store the image in a buffer using savefig(), this has the + # advantage of applying all the default savefig parameters + # such as background color; those would be ignored if you simply + # grab the canvas using Qt + if fig is None: + # find the figure window that has UI focus right now (not necessarily the same as plt.gcf()) + fig_window_text = GetWindowText(GetForegroundWindow()) + for i in plt.get_fignums(): + if plt.figure(i).canvas.get_window_title() == fig_window_text: + fig = plt.figure(i) + break + + buf = io.BytesIO() + fig.savefig(buf) + clipboard().setImage(QImage.fromData(buf.getvalue())) + buf.close() + + +def newfig(*args, **kwargs): + fig = oldfig(*args, **kwargs) + + def clipboard_handler(event): + if event.key == 'ctrl+c': + copyfig() + + fig.canvas.mpl_connect('key_press_event', clipboard_handler) + return fig + + +plt.figure = newfig diff --git a/dist/addcopyfighandler-1.0.1-py2.py3-none-any.whl b/dist/addcopyfighandler-1.0.1-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..618d904abdae4a9a2cec25eeeabf6c1ceda943d8 GIT binary patch literal 2668 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