-
Notifications
You must be signed in to change notification settings - Fork 76
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
Importing pandapipes breaks the matplotlib svg export.
To Reproduce
"""pandapipes import breaks matplotlib svg export.
This script will cause matplotlib to fail with the error:
File "***\matplotlib\backend_bases.py", line 746, in get_capstyle
return self._capstyle.name
^^^^^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'name'
"""
import matplotlib
import matplotlib.pyplot as plt
# This script is fine if pandapipes is not imported.
# Importing pandapipes sets the default capstyle to the string 'round',
# while it has to be an object ``CapStyle('round')``
import pandapipes
print("matplotlib", matplotlib.__version__) # Tested with 3.10.8
print("pandapipes", pandapipes.__version__) # Tested with 0.12.0
fig, ax = plt.subplots()
ax.scatter([1, 2], [1, 2])
# Setting your own capstyle prevents the issue
# ax.scatter([1, 2], [1, 2], capstyle="butt")
# The error is only actually triggered when saving as 'svg'. 'png' is fine.
plt.savefig("./matplotlib_capstyle_error.svg")Error message
Details
Traceback (most recent call last):
File "***\matplotlib_capstyle_error.py", line 25, in <module>
plt.savefig("./matplotlib_capstyle_error.svg")
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "***\matplotlib\pyplot.py", line 1250, in savefig
res = fig.savefig(*args, **kwargs) # type: ignore[func-returns-value]
File "***matplotlib\figure.py", line 3490, in savefig
self.canvas.print_figure(fname, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "***\matplotlib\backends\backend_qtagg.py", line 75, in print_figure
super().print_figure(*args, **kwargs)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "***\matplotlib\backend_bases.py", line 2193, in print_figure
result = print_method(
filename,
...<3 lines>...
bbox_inches_restore=_bbox_inches_restore,
**kwargs)
File "***matplotlib\backend_bases.py", line 2049, in <lambda>
print_method = functools.wraps(meth)(lambda *args, **kwargs: meth(
~~~~^
*args, **{k: v for k, v in kwargs.items() if k not in skip}))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "***s\matplotlib\backends\backend_svg.py", line 1351, in print_svg
self.figure.draw(renderer)
~~~~~~~~~~~~~~~~^^^^^^^^^^
File "***\matplotlib\artist.py", line 94, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
File "***\matplotlib\artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
File "***\matplotlib\figure.py", line 3257, in draw
mimage._draw_list_compositing_images(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
renderer, self, artists, self.suppressComposite)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "***\matplotlib\image.py", line 134, in _draw_list_compositing_images
a.draw(renderer)
~~~~~~^^^^^^^^^^
File "***\matplotlib\artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
File "***s\matplotlib\axes\_base.py", line 3226, in draw
mimage._draw_list_compositing_images(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
renderer, self, artists, self.get_figure(root=True).suppressComposite)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "***\matplotlib\image.py", line 134, in _draw_list_compositing_images
a.draw(renderer)
~~~~~~^^^^^^^^^^
File "***\matplotlib\artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
File "***\matplotlib\collections.py", line 1008, in draw
super().draw(renderer)
~~~~~~~~~~~~^^^^^^^^^^
File "***\matplotlib\artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
File "***\matplotlib\collections.py", line 415, in draw
renderer.draw_markers(
~~~~~~~~~~~~~~~~~~~~~^
gc, paths[0], combined_transform.frozen(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
mpath.Path(offsets), offset_trf, tuple(facecolors[0]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "***\matplotlib\backends\backend_svg.py", line 705, in draw_markers
style = self._get_style_dict(gc, rgbFace)
File "***\matplotlib\backends\backend_svg.py", line 597, in _get_style_dict
if gc.get_capstyle() != 'butt':
~~~~~~~~~~~~~~~^^
File "***\matplotlib\backend_bases.py", line 746, in get_capstyle
return self._capstyle.name
^^^^^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'name'
Expected behavior
The svg export should just work.
Python environment (please complete the following information):
- OS: Windows 11
- pandapipes version 0.12.0
- matplotlib 3.10.8
Possible solution
Update pandapipes\plotting\__init__.py. Import the CapStyle class from matplotlib and set self._capstyle = CapStyle('round') instead of setting it to the string 'round', which causes the error in matplotlib.
import types
from matplotlib.backend_bases import GraphicsContextBase, RendererBase
from matplotlib._enums import CapStyle
from pandapipes.plotting.collections import *
from pandapipes.plotting.generic_geodata import *
from pandapipes.plotting.geo import *
from pandapipes.plotting.pipeflow_results import *
from pandapipes.plotting.simple_plot import *
from pandapower.plotting.collections import add_collections_to_axes, add_cmap_to_collection, \
add_single_collection
class GC(GraphicsContextBase):
"""
"""
def __init__(self):
super().__init__()
self._capstyle = CapStyle('round')
def custom_new_gc(self):
"""
:param self:
:type self:
:return:
:rtype:
"""
return GC()
RendererBase.new_gc = types.MethodType(custom_new_gc, RendererBase)I have created a PR with this simple solution. But I wonder if it is a good design decision that the import of pandapipes changes any default settings for external packages. (In this case from the capstyle 'butt' to 'round'.)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working