Giter Club home page Giter Club logo

rgerum / pylustrator Goto Github PK

View Code? Open in Web Editor NEW
699.0 14.0 37.0 1.29 MB

Visualisations of data are at the core of every publication of scientific research results. They have to be as clear as possible to facilitate the communication of research. As data can have different formats and shapes, the visualisations often have to be adapted to reflect the data as well as possible. We developed Pylustrator, an interface to directly edit python generated matplotlib graphs to finalize them for publication. Therefore, subplots can be resized and dragged around by the mouse, text and annotations can be added. The changes can be saved to the initial plot file as python code.

License: GNU General Public License v3.0

Python 100.00%
matplotlib gui code-generation interactive visualisation

pylustrator's Introduction

docs/images/logo.png


DOC PyTest License DOI

Pylustrator is a software to prepare your figures for publication in a reproducible way. This means you receive a figure representing your data and alongside a generated code file that can exactly reproduce the figure as you put them in the publication, without the need to readjust things in external programs.

Pylustrator offers an interactive interface to find the best way to present your data in a figure for publication. Added formatting and styling can be saved by automatically generated code. To compose multiple figures to panels, pylustrator can compose different subfigures to a single figure.

Please also refer to the Documentation for more information.

Issues, Questions, and Suggestions

Please submit your questions, suggestions, and bug reports to the Issue Tracker

Contributing

You want to contribute? Great! Contributing works best if you creat a pull request with your changes.

  1. Fork the project.
  2. Create a branch for your feature: git checkout -b cool-new-feature
  3. Commit your changes: git commit -am 'My new feature'
  4. Push to the branch: git push origin cool-new-feature
  5. Submit a pull request!

If you are unfamilar with pull requests, you find more information on pull requests in the github help

pylustrator's People

Contributors

joostscheffer avatar labarba avatar rgerum avatar rraadd88 avatar sp94 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pylustrator's Issues

ModuleNotFoundError: No module named 'matplotlib.axes._subplots'

(biotite) ddalab@DP7820-WS:Analysis$ python -c 'import pylustrator'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/ddalab/anaconda3/envs/biotite/lib/python3.11/site-packages/pylustrator/__init__.py", line 22, in <module>
    from .QtGuiDrag import initialize as start
  File "/home/ddalab/anaconda3/envs/biotite/lib/python3.11/site-packages/pylustrator/QtGuiDrag.py", line 33, in <module>
    from .ax_rasterisation import rasterizeAxes, restoreAxes
  File "/home/ddalab/anaconda3/envs/biotite/lib/python3.11/site-packages/pylustrator/ax_rasterisation.py", line 24, in <module>
    from matplotlib.axes._subplots import Axes
ModuleNotFoundError: No module named 'matplotlib.axes._subplots'

iPython support please

Thanks for making pylustrator.
Just that I mostly work in ipython prompt. So It will be really awesome if I can use this within ipython.

Maybe just do my usual stuff in ipython and then when I want to edit things call some magic function which will edit the currently active figure. And once customizing is done, just print the automatically generated code onto the screen instead of trying to edit any file (also just run them for me :) ).

I am not good enough to add this feature myself. At least give me a direction?

Better test coverage

Tests to do:

Text

  • Text properties
  • Text align
  • Text distribute
  • Text delete
  • Text grid align
  • Text font
  • Text snapping

Axes

  • Axes move
  • Axes pos and width/height
  • xlim/ylim
  • xlabel/ylabel
  • ticks
    • major
    • minor
    • scale: linear log
    • labelpad
  • grid
  • despine
  • rectangle
  • arrow
  • annotation
  • align
  • distribute

Legend

  • move
  • properties
  • delete

Figure

  • figure size
  • add image

Lines

  • properties
  • label

Pylustrator Load

  • load script file
  • load image
  • load svg

Programmatic Interface for "Save" menu option

Thanks for creating the package, it's really nice.

I was thinking of adding your package to another software (PyMOL) and it would be really useful to be able to define pylustrator's "Save" option. I don't work with IPythonNotebook.

Thanks, Mat

seems to be broken out of the box...

I installed pylustrator on a macbook pro (intel) using pip. No problems there.
Pasted the "test pylustrator" code from the documentation into jupyter lab, and got the following error. Also tried VS Code, and same result. Any idea what is happening?
image

Crash when resizing the main Figure

Hi,

Trying to do the same changes as in the demo video, the application crashes when I try to resize the main Figure.

I am using Ubuntu 22.04, Python 3.10, Pylustrator runs in a virtual environment.

$ python example_pylustrator.py
Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
Traceback (most recent call last):
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 941, in resizeEvent
    self.updateRuler()
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 867, in updateRuler
    painterX.drawLine(x, l - l1 - 1, x, l - 1)
TypeError: arguments did not match any overloaded call:
  drawLine(self, QLineF): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, QLine): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, int, int, int, int): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, QPoint, QPoint): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, Union[QPointF, QPoint], Union[QPointF, QPoint]): argument 1 has unexpected type 'numpy.float64'
Traceback (most recent call last):
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 932, in showEvent
    self.fitToView()
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 1027, in fitToView
    self.canvas_container.move((self.canvas_canvas.width() - w) / 2 + 5,
TypeError: arguments did not match any overloaded call:
  move(self, QPoint): argument 1 has unexpected type 'float'
  move(self, int, int): argument 1 has unexpected type 'float'
Traceback (most recent call last):
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 939, in resizeEvent
    self.fitToView(True)
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 1016, in fitToView
    self.canvas_container.move((self.canvas_canvas.width() - w) / 2 + 5,
TypeError: arguments did not match any overloaded call:
  move(self, QPoint): argument 1 has unexpected type 'float'
  move(self, int, int): argument 1 has unexpected type 'float'
Traceback (most recent call last):
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QComplexWidgets.py", line 1158, in changeSize
    self.parent.updateRuler()
  File ".../Progs/python/pylustrator/.venv/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 867, in updateRuler
    painterX.drawLine(x, l - l1 - 1, x, l - 1)
TypeError: arguments did not match any overloaded call:
  drawLine(self, QLineF): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, QLine): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, int, int, int, int): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, QPoint, QPoint): argument 1 has unexpected type 'numpy.float64'
  drawLine(self, Union[QPointF, QPoint], Union[QPointF, QPoint]): argument 1 has unexpected type 'numpy.float64'
QPaintDevice: Cannot destroy paint device that is being painted
QPaintDevice: Cannot destroy paint device that is being painted
Erreur de segmentation (core dumped)

Regards

White screen

When I try running the following code I get two white screens.

from matplotlib.pylab import *
π = pi

import pylustrator
pylustrator.start()

t = linspace(0, 1)
x = sin(2 * π * t)
plot(t, x)
show()

image

$ python sine.py 
Traceback (most recent call last):
  File "/usr/local/Caskroom/miniconda/base/envs/book/lib/python3.10/site-packages/pylustrator/QtGuiDrag.py", line 1122, in closeEvent
    if not self.fig.change_tracker.saved:
AttributeError: 'Figure' object has no attribute 'change_tracker'

Commenting out the pylustrator's line, I get the following.

image

I'm using matplotlib 3.5.1.

styling legends

Add more options to style legends in pylustrator. E.g. add a legend to a plot. Define frameon, columns and spacings.

Feature request: loading and editing pickle-dumped figures

First of all, awesome work! Thank you.

Matplotlib folks suggest saving figure objects as a pickle for later modification.

import matplotlib.pyplot as plt
import pickle 

# plot a fancy figure
# ...

fig = plt.gcf()
pickle.dump(fig, open('figObj.pickle', 'wb')) # for future

I was thinking it would be truly amazing if pylustrator could pick up the editing job from those saved picked. Something like this:

import matplotlib.pyplot as plt
import pylustrator
pylustrator.start()

pylustrator.pickle_load('figObj.pickle') # interactive editing 

Looking forward to the future of pylustrator!
Arash

`ImportError: cannot import name 'SubFigure' from 'matplotlib.figure`'

When importing pylustrator (to run the example_pylustrator.py script), I get the message
ImportError: cannot import name 'SubFigure' from 'matplotlib.figure'
and looking into the matplotlib.figure documentation, I cannot find any class named 'SubFigure', only 'Figure' or 'SubplotParams'. pylustrator is installed though.

Would appreciate any info on this. The tool looks so cool and I'd love to make it work on my machine :)

Missing community guidelines

As part of the JOSS review I could not find the community guide lines for contributing. The docs do say how to report bugs (although the text refers to bitbucket but links to github!).

A tool to create insets

I think it would be nice to add a tool to create insets.

I imagine there being a tool with which you can draw a box around a part of the graph, followed by pylustrator creating an inset of that part.

An illustration of what an inset looks like:
image

I think this shouldn't be to hard to implement since matplotlib aleady has the zoomed_inset_axes function.
A demo on how to use this function can be found here: https://matplotlib.org/stable/gallery/axes_grid1/inset_locator_demo2.html

I might try to create something like this for pylustrator sometime in the future.

read an svg file to insert in matplotlib

Hi @rgerum,
I am trying to read an image from an SVG file and insert in matplotlib figure.

import matplotlib.pyplot as plt
import pylustrator as pyl
import numpy as np
from matplotlib.figure import Figure
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from svglib.svglib import svg2rlg

ax = plt.subplot(111)
ax.plot(
    [1, 2, 3], [1, 2, 3],
    'go-',
    label='line 1',
    linewidth=2
 )
# arr_img = plt.imread("stinkbug.svg")
# arr_img = svg2rlg("stinkbug.svg")
arr_img = pyl.load("stinkbug.svg")
im = OffsetImage(arr_img)
ab = AnnotationBbox(im, (1, 0), xycoords='axes fraction')
ax.add_artist(ab)
plt.show()

I tried to use pylustratorpost for reading the svg image. The code works when the input image is in png format. But I am not able to add the same image saved in svg extension(image).

I couldn't successfully insert due to the following error,

    "float".format(self._A.dtype))
TypeError: Image data of dtype object cannot be converted to float

Suggestions on how to fix this will be really helpful.

Error when importing

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/var/folders/cn/qnt666bd35ngv1wd6gczwq900000gn/T/ipykernel_36083/1605426215.py in <module>
----> 1 import pylustrator
      2 # pylustrator.start()

~/opt/anaconda3/lib/python3.7/site-packages/pylustrator/__init__.py in <module>
     20 # along with Pylustrator. If not, see <http://www.gnu.org/licenses/>
     21 
---> 22 from .QtGuiDrag import initialize as start
     23 from .helper_functions import fig_text, add_axes, add_image, despine, changeFigureSize, mark_inset, VoronoiPlot, selectRectangle, mark_inset_pos, draw_from_point_to_bbox, draw_from_point_to_point, loadFigureFromFile, add_letter, add_letters
     24 from .QtGui import initialize as StartColorChooser

~/opt/anaconda3/lib/python3.7/site-packages/pylustrator/QtGuiDrag.py in <module>
     27 from matplotlib import _pylab_helpers
     28 
---> 29 from .QComplexWidgets import *
     30 from .ax_rasterisation import rasterizeAxes, restoreAxes
     31 from .change_tracker import setFigureVariableNames

~/opt/anaconda3/lib/python3.7/site-packages/pylustrator/QComplexWidgets.py in <module>
     31 
     32 from .ax_rasterisation import rasterizeAxes, restoreAxes
---> 33 from .change_tracker import setFigureVariableNames
     34 from .drag_helper import DragManager
     35 from .exception_swallower import swallow_get_exceptions

~/opt/anaconda3/lib/python3.7/site-packages/pylustrator/change_tracker.py in <module>
     36 from matplotlib.patches import Rectangle
     37 from matplotlib.text import Text
---> 38 from natsort import natsorted
     39 
     40 from .exception_swallower import Dummy

~/opt/anaconda3/lib/python3.7/site-packages/natsort/__init__.py in <module>
      1 # -*- coding: utf-8 -*-
      2 
----> 3 from natsort.natsort import (
      4     NatsortKeyType,
      5     OSSortKeyType,

~/opt/anaconda3/lib/python3.7/site-packages/natsort/natsort.py in <module>
    239 
    240 # Exposed for simplicity if one needs the default natsort key.
--> 241 natsort_key = natsort_keygen()
    242 natsort_key.__doc__ = """\
    243 natsort_key(val)

~/opt/anaconda3/lib/python3.7/site-packages/natsort/natsort.py in natsort_keygen(key, alg)
    210             sep = natsort.compat.locale.null_string_locale
    211         else:
--> 212             sep = natsort.compat.locale.null_string
    213         pre_sep = natsort.compat.locale.null_string
    214     regex = utils.regex_chooser(alg)

AttributeError: module 'natsort' has no attribute 'compat'

twinx() seems to blow up matplotlib when pylustrator switched on - 'AxesSubplot' object has no attribute 'collections'

Not sure how, but turning on pylustrator causes matplotlib error without any reference in stack trace to pylustrator.
Presumably something is being overridden or set in pylustrator.start() which causes matplotlib behaviour changes which are causing this.

My code working fine without pylustrator (but could be refined :):

chart_some_data.py

# various other imports omitted

import datetime
import matplotlib.dates as mpdts
import pylustrator

#pylustrator.start() # works with this commented out

# ... omitted data collation, which creates w_dts and w_pps as identical length vectors
# w_pps are floats, w_dts are floats from datetimes using mpdts.date2num()
# ...
fig, axs=plt.subplots(nrows=2, ncols=1)
axs[0].plot(w_dts, w_pps)
ax0_2=axs[0].twinx()

Uncomment the 'pylustrator.start()' line, and matplotlib blows up as follows (cannot get this editor to show the indents on the alternate code lines, sorry):

File "...\dev\chart_some_data.py", line 57, in <module>
ax0_2=axs[0].twinx()
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 4402, in twinx
ax2 = self._make_twin_axes(sharex=self)
File "...\Lib\site-packages\matplotlib\axes\_subplots.py", line 191, in _make_twin_axes
self.get_subplotspec(), *args, label=sentinel, **kwargs)
File "...\Lib\site-packages\matplotlib\figure.py", line 1419, in add_subplot
a = subplot_class_factory(projection_class)(self, *args, **kwargs)
File "...\Lib\site-packages\matplotlib\axes\_subplots.py", line 76, in __init__
self._axes_class.__init__(self, fig, self.figbox, **kwargs)
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 454, in __init__
self.cla()
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 975, in cla
x0, x1 = self._sharex.get_xlim()
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 3085, in get_xlim
return tuple(self.viewLim.intervalx)
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 599, in viewLim
self._unstale_viewLim()
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 595, in _unstale_viewLim
self.autoscale_view(scalex=scalex, scaley=scaley)
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 2384, in autoscale_view
for ax in self._shared_x_axes.get_siblings(self)
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 2386, in <listcomp>
for artist in ax.get_children()]))
File "...\Lib\site-packages\matplotlib\axes\_base.py", line 4218, in get_children
*self.collections,

builtins.AttributeError: 'AxesSubplot' object has no attribute 'collections'

removal of auto save popup window

Hello,

I want to add pylustrator into an application for non programmers. When pylustrator closed without saving, this popup is shown below. This is very useful for a lot of purposes but in this way the users of my application can accidently and easily update main application files which is not wanted. How can I remove this auto save popup? Thank you...

image

plt_draw_text can raise AttributeError on SVG Text nodes

Calling load on a SVG file with <text ...> nodes

  File "/usr/local/lib/python3.7/dist-packages/pylustrator/parse_svg.py", line 643, in parseGroup
    patch_list.append(plt_draw_text(child, trans, style, ids, no_draw=no_draw))
  File "/usr/local/lib/python3.7/dist-packages/pylustrator/parse_svg.py", line 330, in plt_draw_text
    text_content += child.firstChild.nodeValue
AttributeError: 'NoneType' object has no attribute 'nodeValue'

This PR would fix it but I'm not sure if it would break the original use case, which might have been parsing a very different file.
szmoore#1

Make the panels resizeable

Hi,

I just tried Pylustrator with the example code and I like your idea.

I am using Ubuntu 22.04, Python 3.10, Pylustrator runs in a virtual environment.

If the screen resolution is too high (3840 x 2160, scale 200%), the right panel is not usable : the controls are too small.

It would be nice, if you can make the panels resizeable.

Regards

Automatically changing ticks label font size

For changing ticks label font size pylustrator is currently doing it manually tick by tick. For example if I want to change the tick font size to 14 and there are 8 ticks, I get something like the following:

plt.figure(1).axes[0].get_xaxis().get_major_ticks()[0].label1.set_fontsize(14)
plt.figure(1).axes[0].get_xaxis().get_major_ticks()[1].label1.set_fontsize(14)
...
plt.figure(1).axes[0].get_xaxis().get_major_ticks()[7].label1.set_fontsize(14)

I think this could be done programatically by looping through plt.figure(1).axes[0].get_xaxis().get_major_ticks() directly, then you can use the same pylustrator autogenerated code in many figures without having to manually edit the number of ticks by adding or removing lines. For example something like:

# Change major tick font size dynamically
for major_tick in plt.figure(1).axes[0].get_xaxis().get_major_ticks():
    major_tick.label1.set_fontsize(14)

should do it.

Problem with xcb plugin

I am using bash consolo on windows and with a virtualenv, I can import pylustrator but when I execute 'pylustrator.start()' the following error is showing:

qt.qpa.xcb: could not connect to display
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.

Aborted (core dumped)

If I replicate all in the Windows cmd it run correctly.

More than 10 text elements results in IndexError

With more than 10 text elements, pylustrator puts these text elements in the wrong order:

...
fig.text(0.5, 0.5, 'New Text', transform=fig.transFigure)  # id=fig.texts[0].new
fig.texts[0].set_text("A")
fig.texts[0].set_fontsize(12)
fig.texts[0].set_weight("bold")
fig.texts[0].set_position([0.090644, 0.886957])
fig.text(0.5, 0.5, 'New Text', transform=fig.transFigure)  # id=fig.texts[10].new
fig.texts[10].set_text("**")
fig.texts[10].set_weight("bold")
fig.texts[10].set_fontsize(9)
fig.texts[10].set_position([0.914611, 0.469000])
...

Because texts[10] is accessed before it is created, this results in an index error:

IndexError: list index out of range

Preparing metadata error when doing pip install

I'm trying to pip install pylustrator and getting an error (see below for output). I have macOS 12.4 and installing to a fresh conda environment.

Collecting pylustrator
  Using cached pylustrator-1.1.2-py3-none-any.whl (140 kB)
Collecting pyqt5
  Using cached PyQt5-5.15.7.tar.gz (3.2 MB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [29 lines of output]
      Traceback (most recent call last):
        File "/Users/dfelikso/Software/miniconda/miniconda3/envs/pylustrator/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 156, in prepare_metadata_for_build_wheel
          hook = backend.prepare_metadata_for_build_wheel
      AttributeError: module 'sipbuild.api' has no attribute 'prepare_metadata_for_build_wheel'

      During handling of the above exception, another exception occurred:

      Traceback (most recent call last):
        File "/Users/dfelikso/Software/miniconda/miniconda3/envs/pylustrator/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
          main()
        File "/Users/dfelikso/Software/miniconda/miniconda3/envs/pylustrator/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/Users/dfelikso/Software/miniconda/miniconda3/envs/pylustrator/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 160, in prepare_metadata_for_build_wheel
          whl_basename = backend.build_wheel(metadata_directory, config_settings)
        File "/private/var/folders/ny/tt_x0grn03z19yx_r4p_57c80000gq/T/pip-build-env-sjp7jwzq/overlay/lib/python3.10/site-packages/sipbuild/api.py", line 46, in build_wheel
          project = AbstractProject.bootstrap('wheel',
        File "/private/var/folders/ny/tt_x0grn03z19yx_r4p_57c80000gq/T/pip-build-env-sjp7jwzq/overlay/lib/python3.10/site-packages/sipbuild/abstract_project.py", line 87, in bootstrap
          project.setup(pyproject, tool, tool_description)
        File "/private/var/folders/ny/tt_x0grn03z19yx_r4p_57c80000gq/T/pip-build-env-sjp7jwzq/overlay/lib/python3.10/site-packages/sipbuild/project.py", line 584, in setup
          self.apply_user_defaults(tool)
        File "/private/var/folders/ny/tt_x0grn03z19yx_r4p_57c80000gq/T/pip-install-5_ynaead/pyqt5_22e615225c734d568c943d96994bf865/project.py", line 69, in apply_user_defaults
          super().apply_user_defaults(tool)
        File "/private/var/folders/ny/tt_x0grn03z19yx_r4p_57c80000gq/T/pip-build-env-sjp7jwzq/overlay/lib/python3.10/site-packages/pyqtbuild/project.py", line 70, in apply_user_defaults
          super().apply_user_defaults(tool)
        File "/private/var/folders/ny/tt_x0grn03z19yx_r4p_57c80000gq/T/pip-build-env-sjp7jwzq/overlay/lib/python3.10/site-packages/sipbuild/project.py", line 236, in apply_user_defaults
          self.builder.apply_user_defaults(tool)
        File "/private/var/folders/ny/tt_x0grn03z19yx_r4p_57c80000gq/T/pip-build-env-sjp7jwzq/overlay/lib/python3.10/site-packages/pyqtbuild/builder.py", line 67, in apply_user_defaults
          raise PyProjectOptionException('qmake',
      sipbuild.pyproject.PyProjectOptionException
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

Exception when trying to edit text/labels

Great project! Really what was missing for matplotlib

I'm trying to adjust some figures and I get an exception when trying to edit any text object (including axis labels).
As a test-case I generate a plot using the script below:

import matplotlib.pyplot as plt
import pylustrator
import numpy as np
pylustrator.start()

plt.plot(np.arange(10), np.arange(10))
plt.show()

If I then edit the xlabel I get the following exception:

Traceback (most recent call last):
  File "/home/jschrod/.local/lib/python3.9/site-packages/pylustrator/QLinkableWidgets.py", line 120, in updateLink
    elements = self.setLinkedProperty(self.get())
  File "/home/jschrod/.local/lib/python3.9/site-packages/pylustrator/QLinkableWidgets.py", line 67, in set
    if isinstance(self.element, Text) and isinstance(self.element.figure.selection.targets[0].target, Axes):
IndexError: list index out of range

Issue with saving via pylustrator's Save As... menu on Windows

I'm having problems saving using the "Save As..." menu item on Windows. It throws the following exception:

TypeError                                 Traceback (most recent call last)
File [c:\Users\pho\repos\Spike3DWorkEnv\Spike3D\.venv\lib\site-packages\pylustrator\QtGuiDrag.py:522](file:///C:/Users/pho/repos/Spike3DWorkEnv/Spike3D/.venv/lib/site-packages/pylustrator/QtGuiDrag.py:522), in PlotWindow.actionSaveImage(self)
    520 def actionSaveImage(self):
    521     """ save figure as an image """
--> 522     path = QtWidgets.QFileDialog.getSaveFileName(self, "Save Image", getattr(self.fig, "_last_saved_figure", [(None,)])[0][0],
    523                                                  "Images (*.png *.jpg *.pdf)")
    524     if isinstance(path, tuple):
    525         path = str(path[0])

TypeError: getSaveFileName(parent: typing.Optional[QWidget] = None, caption: str = '', directory: str = '', filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0): argument 3 has unexpected type 'WindowsPath'

add alignment options

options to center, or space a selection of objects, e.g. like in Inkscape "align and distribute".

Can not Start Pylustrator

When I run import pylustrator, there always has an error of No module named 'matplotlib.backends.backend_qtagg'
Could you give some suggestions to solve this issue?
image

MatplotlibWidget' object has no attribute '_dpi_ratio

Hi, thanks for your cool package. But I got some issues when try to run your example code using python run_example.py after pip install pylustrator.

  File "xxx/venv/lib/python3.7/site-packages/pylustrator/QComplexWidgets.py", line 1345, in icon
    pm.setDevicePixelRatio(self.canvas._dpi_ratio)
AttributeError: 'MatplotlibWidget' object has no attribute '_dpi_ratio'

Do you have any idea of solving this?

Many thanks,
Jun

svg file editting

Hi, thanks for this nice tools.

I wonder if that works for import svg file generated by python as well. maybe things like plt.imshow?

pylustrator generates unused code?

Hi, first of all - thanks for a great package! I only used it for a while now but I already see how it will make my life easier. :)

The issue I'm reporting is just a small nuisance: during my testing pylustrator seemed to add unused code at the begining of its generated output, namely:

plt.figure(1).ax_dict = {ax.get_label(): ax for ax in plt.figure(1).axes}
import matplotlib as mpl

The mpl import is unused in the generated code below. The ax_dict is also not used anywhere below. If it is used internally by pylustrator it might be useful to add a comment to this line.

Convert an existing matplotlib figure to pylustrator

Hello! Pylustrator is an awesome tool, thanks!

I would like to ask whether you would agree to add a function that converts an existing matplotlib Figure to a figure editable with the Pylustrator GUI.

My use case is the following:

I want to separate data analysis and figure beautification as much as possible, yet keep the figure creation near the analysis for debugging.

src/
    analysis/             #     interactively generate simple
        project1.ipynb    # <-- matplotlib axes for debugging          
paper/
    figure1.py            # <-- beautify the axes and assemble
    document.tex          #     these into an illustration

Data would be analysed in project1.ipynb, and very basic debugging plots would be created there with matplotlib. This analysis notebook should be independent of the way my illustration will look in the paper, and does not need Pylustrator.

When wrapping up the paper, I would want to beautify the axes generated by project1.ipynb and gather these into an illustration using Pylustrator in the figure1.py script. I can already use pickle to dump a matplotlib figure in the notebook, load the dump in the script, and manually adjust the figure. Ideally, I would like to edit the figure from with the Pylustrator GUI. To do that, I need to convert the matplotlib figure into a Pylustrator one.

I know you already support load('project1.ipynb') for a similar use case. But if the computations for analysis are long, it would be nice to separate both aspects. When the notebook has to be executed on a headless high performance computing cluster, pylustrator cannot be used at all.

Thanks again!


I tested a basic implementation of a convertFromPyplot function, copying what you have in loadFromFile(cache = True):

# helper_functions.py
def convertFromPyplot(old, new):

    w, h = old.get_size_inches()
    new.set_size_inches(w, h)

    str(new)  # important! (for some reason I don't know)
    for ax in old.axes:
       old.delaxes(ax)
        new._axstack.add(new._make_key(ax), ax)
        new.bbox._parents.update(old.bbox._parents)
        new.dpi_scale_trans._parents.update(old.dpi_scale_trans._parents)
        replace_all_refs(old.bbox, new.bbox)
        replace_all_refs(old.dpi_scale_trans, new.dpi_scale_trans)
        replace_all_refs(old.canvas, new.canvas)
        replace_all_refs(old, new)

and it appears to be working with this test script:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(1)
ax.text(0.5, 0.5, 'Hello world!')

import pylustrator
pylustrator.start()

newfig = plt.figure()
pylustrator.convertFromPyplot(fig, newfig)
plt.show()

though I'm not sure how robust it is. If it looks good to you, I will be happy to open a pull request!

sort ylim and set_yscale

pylustrator first adds set_ylim command and then the set_yscale which can again overwrite the limits.

Misc `not found`, `not in list` errors

Hi, this project is a great idea.

I get errors when trying to add text to an axis:

Traceback (most recent call last):
  File "C:\conda\lib\site-packages\pylustrator\components\qitem_properties.py", line 1019, in buttonAddTextClicked
    getReference(self.element), getReference(text)), text, ".new")
  File "C:\conda\lib\site-packages\pylustrator\change_tracker.py", line 162, in getReference
    raise TypeError(str(type(element)) + " not found")
TypeError: <class 'matplotlib.text.Text'> not found

or add an arrow:

Traceback (most recent call last):
  File "C:\conda\lib\site-packages\pylustrator\components\qitem_properties.py", line 1085, in buttonAddArrowClicked
    p._posA_posB[0], p._posA_posB[1], getReference(p)),
  File "C:\conda\lib\site-packages\pylustrator\change_tracker.py", line 104, in getReference
    index = element.axes.patches.index(element)
ValueError: <matplotlib.patches.FancyArrowPatch object at 0x0000017A2D76B820> is not in list

or change a Line2D's property:

<matplotlib.lines.Line2D object at 0x000001F3198B2160> is not in list

The edits are displayed in the plot, but are not saved to the .py file.

pylustrator version 1.2.1
matplotlib version 3.5.1

pylustrator not working in google colab

#plotting the data
import seaborn as sns
import pylustrator
pylustrator.start()
sns.countplot(x = 'Tool',hue = 'Condition',data = df,palette=['blue', 'green'])
plt.show()

when I run this code googlecolab session crashed

File Not Found

I receive the following error when attempting to run the example.

FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\<>\AppData\Local\Temp\ipykernel_16232\1628941459.py'

How to resolve?

Thanks.

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.