pyroll-core 3.0.0.post4__tar.gz → 3.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/PKG-INFO +2 -1
  2. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/__init__.py +3 -2
  3. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/config.py +20 -17
  4. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/repr.py +14 -7
  5. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll/hookimpls.py +15 -6
  6. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/profile.py +6 -1
  7. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/shapes.py +55 -12
  8. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/.gitignore +0 -0
  9. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/LICENSE +0 -0
  10. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/README.md +0 -0
  11. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/hatch.toml +0 -0
  12. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyproject.toml +0 -0
  13. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/disk_elements/__init__.py +0 -0
  14. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/disk_elements/disk_element_unit.py +0 -0
  15. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/disk_elements/hookimpls.py +0 -0
  16. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/__init__.py +0 -0
  17. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/base.py +0 -0
  18. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/__init__.py +0 -0
  19. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/box.py +0 -0
  20. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/constricted_box.py +0 -0
  21. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/boxes/upset_box.py +0 -0
  22. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/__init__.py +0 -0
  23. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/diamond.py +0 -0
  24. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/gothic.py +0 -0
  25. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/diamonds/square.py +0 -0
  26. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/equivalent_ripped_groove.py +0 -0
  27. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/flat.py +0 -0
  28. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/generic_elongation.py +0 -0
  29. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/generic_elongation_solvers.py +0 -0
  30. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/hexagonal.py +0 -0
  31. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/__init__.py +0 -0
  32. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/circular_oval.py +0 -0
  33. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/constricted_circular_oval.py +0 -0
  34. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/constricted_swedish_oval.py +0 -0
  35. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/flat_oval.py +0 -0
  36. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/oval_3radii.py +0 -0
  37. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/oval_3radii_flanked.py +0 -0
  38. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/swedish_oval.py +0 -0
  39. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/ovals/upset_oval.py +0 -0
  40. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/rounds/__init__.py +0 -0
  41. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/rounds/false_round.py +0 -0
  42. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/rounds/round.py +0 -0
  43. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/grooves/spline.py +0 -0
  44. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/hooks.py +0 -0
  45. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/log.py +0 -0
  46. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/profile/__init__.py +0 -0
  47. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/profile/hookimpls.py +0 -0
  48. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/profile/profile.py +0 -0
  49. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll/__init__.py +0 -0
  50. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll/roll.py +0 -0
  51. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/__init__.py +0 -0
  52. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/base.py +0 -0
  53. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/deformation_unit.py +0 -0
  54. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/__init__.py +0 -0
  55. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/base_roll_pass.py +0 -0
  56. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/deformation_unit.py +0 -0
  57. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/disk_element.py +0 -0
  58. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/helpers.py +0 -0
  59. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/roll.py +0 -0
  60. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/symmetric_roll_pass.py +0 -0
  61. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/three_roll_pass.py +0 -0
  62. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/hookimpls/two_roll_pass.py +0 -0
  63. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/symmetric_roll_pass.py +0 -0
  64. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/three_roll_pass.py +0 -0
  65. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/roll_pass/two_roll_pass.py +0 -0
  66. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/rotator/__init__.py +0 -0
  67. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/rotator/hookimpls.py +0 -0
  68. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/rotator/rotator.py +0 -0
  69. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/sequence/__init__.py +0 -0
  70. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/sequence/hookimpls.py +0 -0
  71. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/sequence/sequence.py +0 -0
  72. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/transport/__init__.py +0 -0
  73. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/transport/cooling_pipe.py +0 -0
  74. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/transport/hookimpls/__init__.py +0 -0
  75. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/transport/hookimpls/cooling_pipe.py +0 -0
  76. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/transport/hookimpls/transport.py +0 -0
  77. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/transport/transport.py +0 -0
  78. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/unit/__init__.py +0 -0
  79. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/unit/hookimpls.py +0 -0
  80. {pyroll_core-3.0.0.post4 → pyroll_core-3.0.1}/pyroll/core/unit/unit.py +0 -0
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyroll-core
3
- Version: 3.0.0.post4
3
+ Version: 3.0.1
4
4
  Summary: PyRoll rolling simulation framework - core library.
5
5
  Project-URL: Homepage, https://pyroll-project.github.io
6
6
  Project-URL: Repository, https://github.com/pyroll-project/pyroll-core
7
7
  Project-URL: Documentation, https://pyroll.readthedocs.io/en/latest
8
8
  Author-email: Max Weiner <max.weiner@imf.tu-freiberg.de>, Christoph Renzing <christoph.renzing@imf.tu-freiberg.de>, Matthias Schmidtchen <matthias.schmidtchen@imf.tu-freiberg.de>, Max Stirl <max.stirl@imf.tu-freiberg.de>
9
+ License: BSD-3-Clause
9
10
  Classifier: Development Status :: 5 - Production/Stable
10
11
  Classifier: Framework :: Hatch
11
12
  Classifier: Framework :: IPython
@@ -11,9 +11,9 @@ from .rotator import Rotator
11
11
  from .sequence import PassSequence
12
12
  from .hooks import Hook, HookHost, HookFunction, root_hooks
13
13
  from .disk_elements import DiskElementUnit
14
- from .config import Config, config
14
+ from .config import Config, config, PlottingBackend
15
15
 
16
- VERSION = "3.0.0post4"
16
+ VERSION = "3.0.1"
17
17
 
18
18
  root_hooks.extend(
19
19
  [
@@ -32,6 +32,7 @@ root_hooks.extend(
32
32
  BaseRollPass.OutProfile.filling_error,
33
33
  BaseRollPass.OutProfile.cross_section_error,
34
34
  BaseRollPass.OutProfile.velocity,
35
+ BaseRollPass.InProfile.velocity,
35
36
  PassSequence.log_elongation,
36
37
  BaseRollPass.OutProfile.technologically_orientated_cross_section,
37
38
  BaseRollPass.technologically_orientated_contour_lines,
@@ -1,19 +1,20 @@
1
1
  import os
2
+ from enum import Enum
2
3
  from pathlib import Path
3
4
  from typing import Optional, Iterable, Mapping, Any, Callable
4
5
 
5
6
 
6
7
  class ConfigValue:
7
8
  """Helper descriptor for storing configuration values, able to determine the value from explictly set values,
8
- environment variables and default values."""
9
+ environment variables and default values."""
9
10
 
10
11
  def __init__(
11
- self,
12
- default,
13
- *,
14
- env_var: Optional[str] = None,
15
- env_var_prefix: Optional[str] = None,
16
- parser: Optional[Callable[[str], Any]] = None
12
+ self,
13
+ default,
14
+ *,
15
+ env_var: Optional[str] = None,
16
+ env_var_prefix: Optional[str] = None,
17
+ parser: Optional[Callable[[str], Any]] = None,
17
18
  ):
18
19
  self.default = default
19
20
  self.type = type(default)
@@ -26,7 +27,7 @@ class ConfigValue:
26
27
  self.owner = owner
27
28
  self.name = name
28
29
  if not self._env_var_prefix:
29
- self._env_var_prefix = self.owner.__module__.upper().replace('.', '_')
30
+ self._env_var_prefix = self.owner.__module__.upper().replace(".", "_")
30
31
 
31
32
  @property
32
33
  def env_var(self):
@@ -83,11 +84,7 @@ class ConfigValue:
83
84
  class ConfigMeta(type):
84
85
  def to_dict(cls):
85
86
  """Return the config values of this class as dict."""
86
- return {
87
- n: v
88
- for n, v in type(cls).__dict__.items()
89
- if isinstance(v, ConfigValue)
90
- }
87
+ return {n: v for n, v in type(cls).__dict__.items() if isinstance(v, ConfigValue)}
91
88
 
92
89
  def update(cls, d: dict[str, Any]):
93
90
  """
@@ -138,10 +135,7 @@ def config(env_var_prefix):
138
135
  else:
139
136
  # noinspection PyProtectedMember
140
137
  meta_dict[n] = ConfigValue(
141
- default=v.default,
142
- env_var_prefix=env_var_prefix,
143
- env_var=v._env_var,
144
- parser=v.parser
138
+ default=v.default, env_var_prefix=env_var_prefix, env_var=v._env_var, parser=v.parser
145
139
  )
146
140
 
147
141
  meta = type(cls.__name__ + "Meta", (ConfigMeta,), meta_dict)
@@ -151,9 +145,15 @@ def config(env_var_prefix):
151
145
  return dec
152
146
 
153
147
 
148
+ class PlottingBackend(Enum):
149
+ PLOTLY = 1
150
+ MATPLOTLIB = 2
151
+
152
+
154
153
  @config("PYROLL_CORE")
155
154
  class Config:
156
155
  """Configuration class for ``pyroll.core``."""
156
+
157
157
  ROLL_PASS_AUTO_ROTATION = True
158
158
  """Whether to enable automatic rotation of incoming profiles in roll passes by default."""
159
159
 
@@ -199,3 +199,6 @@ class Config:
199
199
 
200
200
  PLOT_RESOLUTION = 100
201
201
  """Resolution of plots in dots per inches (dpi)."""
202
+
203
+ PREFERRED_PLOTTING_BACKEND = PlottingBackend.PLOTLY
204
+ """Sets the preferred plotting backend to use when both matplotlib and plotly are installed."""
@@ -1,8 +1,8 @@
1
1
  import html
2
2
  from abc import ABC, abstractmethod
3
3
  from io import StringIO
4
- from .config import Config
5
- from .log import global_logger
4
+
5
+ from .config import Config, PlottingBackend
6
6
 
7
7
 
8
8
  class ReprMixin(ABC):
@@ -49,11 +49,18 @@ class ReprMixin(ABC):
49
49
 
50
50
  :returns: either a plotly or matplotlib figure object
51
51
  """
52
-
53
- try:
54
- return self.plot_plotly()
55
- except (NotImplementedError, ImportError):
56
- return self.plot_matplotlib()
52
+ if Config.PREFERRED_PLOTTING_BACKEND == PlottingBackend.PLOTLY:
53
+ try:
54
+ return self.plot_plotly()
55
+ except (NotImplementedError, ImportError):
56
+ return self.plot_matplotlib()
57
+ elif Config.PREFERRED_PLOTTING_BACKEND == PlottingBackend.MATPLOTLIB:
58
+ try:
59
+ return self.plot_matplotlib()
60
+ except (NotImplementedError, ImportError):
61
+ return self.plot_plotly()
62
+
63
+ raise ValueError("Invalid value given for 'Config.PREFERRED_PLOTTING_BACKEND'. Value must be a member of the pyroll.core.PlottingBackend enumeration.")
57
64
 
58
65
  def __str__(self):
59
66
  return type(self).__qualname__
@@ -25,18 +25,27 @@ def roll_power(self: Roll):
25
25
 
26
26
 
27
27
  @Roll.working_velocity
28
- def working_velocity(self: Roll):
29
- return self.rotational_frequency * self.working_radius * 2 * np.pi
28
+ def working_velocity(self: Roll, cycle):
29
+ if not cycle:
30
+ return self.rotational_frequency * self.working_radius * 2 * np.pi
30
31
 
31
32
 
32
33
  @Roll.surface_velocity
33
- def surface_velocity(self: Roll):
34
- return self.rotational_frequency * self.nominal_radius * 2 * np.pi
34
+ def surface_velocity(self: Roll, cycle):
35
+ if not cycle:
36
+ return self.rotational_frequency * self.nominal_radius * 2 * np.pi
35
37
 
36
38
 
37
39
  @Roll.rotational_frequency
38
- def rotational_frequency(self: Roll):
39
- return self.surface_velocity / (2 * np.pi * self.nominal_radius)
40
+ def rotational_frequency(self: Roll, cycle):
41
+ if not cycle:
42
+ return self.surface_velocity / (2 * np.pi * self.nominal_radius)
43
+
44
+
45
+ @Roll.rotational_frequency
46
+ def rotational_frequency(self: Roll, cycle):
47
+ if not cycle:
48
+ return self.working_velocity / (2 * np.pi * self.working_radius)
40
49
 
41
50
 
42
51
  @Roll.width
@@ -88,6 +88,11 @@ def classifiers(self: BaseRollPass.OutProfile):
88
88
  return set(self.roll_pass.classifiers)
89
89
 
90
90
 
91
+ @BaseRollPass.InProfile.velocity
92
+ def in_velocity(self: BaseRollPass.InProfile):
93
+ return self.roll_pass.out_profile.velocity * self.unit.out_profile.cross_section.area / self.cross_section.area
94
+
95
+
91
96
  @BaseRollPass.OutProfile.velocity
92
- def velocity(self: BaseRollPass.OutProfile):
97
+ def out_velocity(self: BaseRollPass.OutProfile):
93
98
  return self.roll_pass.velocity
@@ -91,23 +91,21 @@ def multi_polygon_plot_matplotlib(self: MultiPolygon):
91
91
  ax.set_aspect("equal", "datalim")
92
92
  ax.grid(lw=0.5)
93
93
 
94
- for g, c in zip(self.geoms, plt.color_sequences["default"]):
95
- ax.plot(*g.boundary.xy, color=c)
96
- ax.fill(*g.boundary.xy, alpha=0.5, color=c)
94
+ for g in self.geoms:
95
+ l = ax.plot(*g.boundary.xy)
96
+ ax.fill(*g.boundary.xy, alpha=0.5, color=l[0].get_color())
97
97
  return fig
98
98
 
99
99
 
100
100
  def multi_polygon_plot_plotly(self: MultiPolygon):
101
101
  import plotly.graph_objects as pgo
102
- from pandas import DataFrame
103
102
 
104
103
  fig = pgo.Figure()
105
104
 
106
105
  for g in self.geoms:
107
- fig.add_trace(pgo.line(
108
- x=[g.boundary.xy[0] for g in self.geoms],
109
- y=[g.boundary.xy[1] for g in self.geoms],
110
- labels={"y": "y", "x": "z"},
106
+ fig.add_trace(pgo.Line(
107
+ x=np.array(g.boundary.xy[0]),
108
+ y=np.array(g.boundary.xy[1]),
111
109
  ))
112
110
 
113
111
  fig.update_traces(
@@ -116,9 +114,12 @@ def multi_polygon_plot_plotly(self: MultiPolygon):
116
114
 
117
115
  fig.update_yaxes(
118
116
  scaleanchor="x",
119
- scaleratio=1
117
+ scaleratio=1,
118
+ title="y"
120
119
  )
121
120
 
121
+ fig.update_xaxes(title="z")
122
+
122
123
  return fig
123
124
 
124
125
 
@@ -134,7 +135,7 @@ def line_string_plot_matplotlib(self: LineString):
134
135
  ax.set_aspect("equal", "datalim")
135
136
  ax.grid(lw=0.5)
136
137
 
137
- ax.plot(*self.xy, color="k")
138
+ ax.plot(*self.xy)
138
139
  return fig
139
140
 
140
141
 
@@ -147,8 +148,6 @@ def line_string_plot_plotly(self: LineString):
147
148
  labels={"y": "y", "x": "z"},
148
149
  )
149
150
 
150
- fig.update_traces(line_color="black")
151
-
152
151
  fig.update_yaxes(
153
152
  scaleanchor="x",
154
153
  scaleratio=1
@@ -157,6 +156,45 @@ def line_string_plot_plotly(self: LineString):
157
156
  return fig
158
157
 
159
158
 
159
+ def multi_line_string_plot_matplotlib(self: MultiLineString):
160
+ import matplotlib.pyplot as plt
161
+
162
+ fig: plt.Figure = plt.figure()
163
+ ax: plt.Axes = fig.subplots()
164
+
165
+ ax.set_ylabel("y")
166
+ ax.set_xlabel("z")
167
+
168
+ ax.set_aspect("equal", "datalim")
169
+ ax.grid(lw=0.5)
170
+
171
+ for g in self.geoms:
172
+ ax.plot(*g.xy)
173
+ return fig
174
+
175
+
176
+ def multi_line_string_plot_plotly(self: MultiLineString):
177
+ import plotly.graph_objects as pgo
178
+
179
+ fig = pgo.Figure()
180
+
181
+ for g in self.geoms:
182
+ fig.add_trace(pgo.Line(
183
+ x=np.array(g.xy[0]),
184
+ y=np.array(g.xy[1]),
185
+ ))
186
+
187
+ fig.update_yaxes(
188
+ scaleanchor="x",
189
+ scaleratio=1,
190
+ title="y"
191
+ )
192
+
193
+ fig.update_xaxes(title="z")
194
+
195
+ return fig
196
+
197
+
160
198
  for cls in [
161
199
  LineString,
162
200
  MultiLineString,
@@ -203,6 +241,11 @@ LineString._plot_matplotlib_ = line_string_plot_matplotlib
203
241
  # noinspection PyProtectedMember
204
242
  LineString._plot_plotly_ = line_string_plot_plotly
205
243
 
244
+ # noinspection PyProtectedMember
245
+ MultiLineString._plot_matplotlib_ = multi_line_string_plot_matplotlib
246
+ # noinspection PyProtectedMember
247
+ MultiLineString._plot_plotly_ = multi_line_string_plot_plotly
248
+
206
249
  _RECTANGLE_CORNERS = np.asarray(
207
250
  [
208
251
  (-0.5, -0.5),
File without changes
File without changes