Skip to content

Commit 9997bcb

Browse files
Added method to plot Edb in Linux with Client Server mode (#791)
* Added method to plot Edb in Linux with Client Server mode * Black fix * Black fix * Apply suggestions from code review Co-authored-by: Maxime Rey <[email protected]> Co-authored-by: Maxime Rey <[email protected]>
1 parent a8503d2 commit 9997bcb

File tree

9 files changed

+1353
-1264
lines changed

9 files changed

+1353
-1264
lines changed

pyaedt/application/Analysis2D.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def plot(
165165
166166
Returns
167167
-------
168-
:class:`pyaedt.modules.AdvancedPostProcessing.ModelPlotter`
168+
:class:`pyaedt.generic.plot.ModelPlotter`
169169
Model Object.
170170
"""
171171
if is_ironpython:

pyaedt/application/Analysis3D.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ def plot(
200200
201201
Returns
202202
-------
203-
:class:`pyaedt.modules.AdvancedPostProcessing.ModelPlotter`
203+
:class:`pyaedt.generic.plot.ModelPlotter`
204204
Model Object.
205205
"""
206206
if is_ironpython:

pyaedt/application/AnalysisIcepak.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def plot(
166166
167167
Returns
168168
-------
169-
:class:`pyaedt.modules.AdvancedPostProcessing.ModelPlotter`
169+
:class:`pyaedt.generic.plot.ModelPlotter`
170170
Model Object.
171171
"""
172172
if is_ironpython:

pyaedt/edb_core/EDB_Data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ def _eval_arc_points(p1, p2, h, n=6, tol=1e-12):
237237
yr = []
238238
for i in range(n):
239239
i += 1
240-
dth = (i/(n+1)) * th
240+
dth = (float(i)/(n+1)) * th
241241
xi = xc + r * math.cos(alpha-dth)
242242
yi = yc + r * math.sin(alpha-dth)
243243
xr.append(xi)

pyaedt/edb_core/nets.py

Lines changed: 68 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from __future__ import absolute_import
2-
import warnings
32
import time
43
import math
54

@@ -8,18 +7,7 @@
87
from pyaedt.modeler.GeometryOperators import GeometryOperators
98
from pyaedt.generic.constants import CSS4_COLORS
109
from pyaedt.edb_core.EDB_Data import EDBNetsData
11-
12-
if not is_ironpython:
13-
try:
14-
from matplotlib import pyplot as plt
15-
from matplotlib.path import Path
16-
from matplotlib.patches import PathPatch
17-
except ImportError:
18-
mess = "The Matplotlib module is required to run some functionalities.\n"
19-
mess += "Install with \npip install matplotlib"
20-
warnings.warn(mess)
21-
except:
22-
pass
10+
from pyaedt.generic.plot import plot_matplotlib
2311

2412

2513
class EdbNets(object):
@@ -221,10 +209,14 @@ def _get_points_for_plot(self, my_net_points):
221209
return x, y
222210

223211
@aedt_exception_handler
224-
def plot(
225-
self, nets, layers=None, color_by_net=False, show_legend=True, save_plot=None, outline=None, size=(2000, 1000)
212+
def get_plot_data(
213+
self,
214+
nets,
215+
layers=None,
216+
color_by_net=False,
217+
outline=None,
226218
):
227-
"""Plot a Net to Matplotlib 2D Chart.
219+
"""Return List of points for Matplotlib 2D Chart.
228220
229221
Parameters
230222
----------
@@ -235,35 +227,21 @@ def plot(
235227
color_by_net : bool, optional
236228
If `True` the plot will be colored by net.
237229
If `False` the plot will be colored by layer. (default)
238-
show_legend : bool, optional
239-
If `True` the legend is shown in the plot. (default)
240-
If `False` the legend is not shown.
241-
save_plot : str, optional
242-
If `None` the plot will be shown.
243-
If a file path is specified the plot will be saved to such file.
244230
outline : list, optional
245231
List of points of the outline to plot.
246-
size : tuple, optional
247-
Image size in pixel (width, height).
248232
"""
249233
start_time = time.time()
250-
if is_ironpython:
251-
self._logger.warning("Plot functionalities are enabled only in CPython.")
252-
return False
234+
color_index = 0
253235
if not layers:
254236
layers = list(self._pedb.core_stackup.signal_layers.keys())
255237
if not nets:
256238
nets = list(self.nets.keys())
239+
objects_lists = []
257240
label_colors = {}
258-
color_index = 0
259-
dpi = 100.0
260-
figsize = (size[0] / dpi, size[1] / dpi)
261-
fig, ax = plt.subplots(figsize=figsize)
262241
if outline:
263242
x1 = [i[0] for i in outline]
264243
y1 = [i[1] for i in outline]
265-
plt.fill(x1, y1, c="b", label="Outline", alpha=0.3)
266-
244+
objects_lists.append([x1, y1, "b", "Outline", 0.3, "fill"])
267245
if isinstance(nets, str):
268246
nets = [nets]
269247

@@ -279,26 +257,27 @@ def plot(
279257
if label not in label_colors:
280258
color = path.layer.GetColor()
281259
try:
282-
c = (color.Item1 / 255, color.Item2 / 255, color.Item3 / 255)
260+
c = (float(color.Item1 / 255), float(color.Item2 / 255), float(color.Item3 / 255))
283261
label_colors[label] = c
284262
except:
285263
label_colors[label] = list(CSS4_COLORS.keys())[color_index]
286264
color_index += 1
287265
if color_index >= len(CSS4_COLORS):
288266
color_index = 0
289-
plt.fill(x, y, c=label_colors[label], label=label, alpha=0.4)
267+
objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
290268
else:
291-
plt.fill(x, y, c=label_colors[label], alpha=0.4)
269+
objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
270+
292271
else:
293272
label = "Net " + net_name
294273
if label not in label_colors:
295274
label_colors[label] = list(CSS4_COLORS.keys())[color_index]
296275
color_index += 1
297276
if color_index >= len(CSS4_COLORS):
298277
color_index = 0
299-
plt.fill(x, y, c=label_colors[label], label=label, alpha=0.4)
278+
objects_lists.append([x, y, label_colors[label], label, 0.4, "fill"])
300279
else:
301-
plt.fill(x, y, c=label_colors[label], alpha=0.4)
280+
objects_lists.append([x, y, label_colors[label], None, 0.4, "fill"])
302281

303282
for poly in self._pedb.core_primitives.polygons:
304283
if poly.is_void:
@@ -311,43 +290,42 @@ def plot(
311290
continue
312291
x, y = GeometryOperators.orient_polygon(xt, yt, clockwise=True)
313292
vertices = [(i, j) for i, j in zip(x, y)]
314-
codes = [Path.LINETO for _ in vertices]
315-
codes[0] = Path.MOVETO
293+
codes = [2 for _ in vertices]
294+
codes[0] = 1
316295
vertices.append((0, 0))
317-
codes.append(Path.CLOSEPOLY)
296+
codes.append(79)
318297

319298
for void in poly.voids:
320299
xvt, yvt = void.points()
321300
if xvt:
322301
xv, yv = GeometryOperators.orient_polygon(xvt, yvt, clockwise=False)
323302
tmpV = [(i, j) for i, j in zip(xv, yv)]
324303
vertices.extend(tmpV)
325-
tmpC = [Path.LINETO for _ in tmpV]
326-
tmpC[0] = Path.MOVETO
304+
tmpC = [2 for _ in tmpV]
305+
tmpC[0] = 1
327306
codes.extend(tmpC)
328307
vertices.append((0, 0))
329-
codes.append(Path.CLOSEPOLY)
330-
331-
# create Path object from vertices and codes
332-
path = Path(vertices, codes)
308+
codes.append(79)
333309

334310
if not color_by_net:
335311
label = "Layer " + layer_name
336312
if label not in label_colors:
337313
color = poly.GetLayer().GetColor()
338314
try:
339-
c = (color.Item1 / 255, color.Item2 / 255, color.Item3 / 255)
315+
c = (float(color.Item1 / 255), float(color.Item2 / 255), float(color.Item3 / 255))
340316
label_colors[label] = c
341317
except:
342318
label_colors[label] = list(CSS4_COLORS.keys())[color_index]
343319
color_index += 1
344320
if color_index >= len(CSS4_COLORS):
345321
color_index = 0
346322
# create patch from path
347-
patch = PathPatch(path, color=label_colors[label], alpha=0.4, label=label)
323+
objects_lists.append([vertices, codes, label_colors[label], label, 0.4, "path"])
324+
348325
else:
349326
# create patch from path
350-
patch = PathPatch(path, color=label_colors[label], alpha=0.4)
327+
objects_lists.append([vertices, codes, label_colors[label], "", 0.4, "path"])
328+
351329
else:
352330
label = "Net " + net_name
353331
if label not in label_colors:
@@ -356,24 +334,50 @@ def plot(
356334
if color_index >= len(CSS4_COLORS):
357335
color_index = 0
358336
# create patch from path
359-
patch = PathPatch(path, color=label_colors[label], alpha=0.4, label=label)
337+
objects_lists.append([vertices, codes, label_colors[label], label, 0.4, "path"])
360338
else:
361339
# create patch from path
362-
patch = PathPatch(path, color=label_colors[label], alpha=0.4)
340+
objects_lists.append([vertices, codes, label_colors[label], "", 0.4, "path"])
341+
end_time = time.time() - start_time
342+
self._logger.info("Nets Point Generation time %s seconds", round(end_time, 3))
343+
return objects_lists
363344

364-
# plot the patch
365-
ax.add_patch(patch)
345+
@aedt_exception_handler
346+
def plot(
347+
self, nets, layers=None, color_by_net=False, show_legend=True, save_plot=None, outline=None, size=(2000, 1000)
348+
):
349+
"""Plot a Net to Matplotlib 2D Chart.
366350
367-
ax.set(xlabel="X (m)", ylabel="Y (m)", title=self._pedb.active_cell.GetName())
368-
if show_legend:
369-
ax.legend()
370-
ax.axis("equal")
371-
end_time = time.time() - start_time
372-
self._logger.info("Plot Generation time %s seconds", round(end_time, 3))
373-
if save_plot:
374-
plt.savefig(save_plot)
375-
else:
376-
plt.show()
351+
Parameters
352+
----------
353+
nets : str, list
354+
Name of the net or list of nets to plot. If `None` all nets will be plotted.
355+
layers : str, list, optional
356+
Name of the layers to include in the plot. If `None` all the signal layers will be considered.
357+
color_by_net : bool, optional
358+
If `True` the plot will be colored by net.
359+
If `False` the plot will be colored by layer. (default)
360+
show_legend : bool, optional
361+
If `True` the legend is shown in the plot. (default)
362+
If `False` the legend is not shown.
363+
save_plot : str, optional
364+
If `None` the plot will be shown.
365+
If a file path is specified the plot will be saved to such file.
366+
outline : list, optional
367+
List of points of the outline to plot.
368+
size : tuple, optional
369+
Image size in pixel (width, height). Default value is ``(2000, 1000)``
370+
"""
371+
if is_ironpython:
372+
self._logger.warning("Plot functionalities are enabled only in CPython.")
373+
return False
374+
object_lists = self.get_plot_data(
375+
nets,
376+
layers,
377+
color_by_net,
378+
outline,
379+
)
380+
plot_matplotlib(object_lists, size, show_legend, "X (m)", "Y (m)", self._pedb.active_cell.GetName(), save_plot)
377381

378382
@aedt_exception_handler
379383
def is_power_gound_net(self, netname_list):

pyaedt/generic/general_methods.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,24 @@ def convert_remote_object(arg):
134134
"""
135135
if _check_types(arg) == "list":
136136
if arg.__len__() > 0:
137-
if isinstance(arg[0], (int, float, str, dict)):
138-
return list(eval(str(arg)))
137+
if (
138+
isinstance(arg[0], (int, float, str))
139+
or _check_types(arg[0]) == "list"
140+
or _check_types(arg[0]) == "dict"
141+
):
142+
a = list(eval(str(arg)))
143+
for i, el in enumerate(a):
144+
a[i] = convert_remote_object(el)
145+
return a
139146
else:
140147
return [arg[i] for i in range(arg.__len__())]
141148
else:
142149
return []
143150
elif _check_types(arg) == "dict":
144-
return dict(eval(str(arg)))
151+
a = dict(eval(str(arg)))
152+
for k, v in a.items():
153+
a[k] = convert_remote_object(v)
154+
return a
145155
return arg
146156

147157

0 commit comments

Comments
 (0)