Skip to content
Snippets Groups Projects
Commit c3793718 authored by Oscar Gustafsson's avatar Oscar Gustafsson :bicyclist:
Browse files

Use constrained layout for plots

parent 276856f0
No related branches found
No related tags found
No related merge requests found
Pipeline #158936 failed
...@@ -260,7 +260,7 @@ class Resource(HardwareBlock): ...@@ -260,7 +260,7 @@ class Resource(HardwareBlock):
**kwargs **kwargs
Passed to :meth:`~b_asic.resources.ProcessCollection.plot`. Passed to :meth:`~b_asic.resources.ProcessCollection.plot`.
""" """
fig, ax = plt.subplots() fig, ax = plt.subplots(layout="constrained")
self.plot_content(ax, **kwargs) self.plot_content(ax, **kwargs)
if title: if title:
fig.suptitle(title) fig.suptitle(title)
...@@ -294,7 +294,7 @@ class Resource(HardwareBlock): ...@@ -294,7 +294,7 @@ class Resource(HardwareBlock):
This is visible in enriched shells, but the object itself has no further This is visible in enriched shells, but the object itself has no further
meaning (it is a Matplotlib Figure). meaning (it is a Matplotlib Figure).
""" """
fig, ax = plt.subplots() fig, ax = plt.subplots(layout="constrained")
self.plot_content(ax) self.plot_content(ax)
return fig return fig
......
...@@ -25,7 +25,7 @@ class MPLWindow(QDialog): ...@@ -25,7 +25,7 @@ class MPLWindow(QDialog):
self._dialog_layout = QVBoxLayout() self._dialog_layout = QVBoxLayout()
self.setLayout(self._dialog_layout) self.setLayout(self._dialog_layout)
self._plot_fig = Figure(figsize=(5, 4), layout="compressed") self._plot_fig = Figure(figsize=(5, 4), layout="constrained")
self._plot_axes = self._plot_fig.subplots(*subplots) self._plot_axes = self._plot_fig.subplots(*subplots)
self._plot_canvas = FigureCanvas(self._plot_fig) self._plot_canvas = FigureCanvas(self._plot_fig)
......
...@@ -580,7 +580,7 @@ class ProcessCollection: ...@@ -580,7 +580,7 @@ class ProcessCollection:
# Set up the Axes object # Set up the Axes object
if ax is None: if ax is None:
_, _ax = plt.subplots() _, _ax = plt.subplots(layout="constrained")
else: else:
_ax = ax _ax = ax
...@@ -724,7 +724,7 @@ class ProcessCollection: ...@@ -724,7 +724,7 @@ class ProcessCollection:
title : str, optional title : str, optional
Figure title. Figure title.
""" """
fig, ax = plt.subplots() fig, ax = plt.subplots(layout="constrained")
self.plot( self.plot(
ax=ax, ax=ax,
show_name=show_name, show_name=show_name,
...@@ -1122,7 +1122,7 @@ class ProcessCollection: ...@@ -1122,7 +1122,7 @@ class ProcessCollection:
This is automatically displayed in e.g. Jupyter Qt console. This is automatically displayed in e.g. Jupyter Qt console.
""" """
fig, ax = plt.subplots() fig, ax = plt.subplots(layout="constrained")
self.plot(ax=ax, show_markers=False) self.plot(ax=ax, show_markers=False)
f = io.StringIO() f = io.StringIO()
fig.savefig(f, format="svg") # type: ignore fig.savefig(f, format="svg") # type: ignore
...@@ -1628,7 +1628,7 @@ class ProcessCollection: ...@@ -1628,7 +1628,7 @@ class ProcessCollection:
title : str title : str
Figure title. Figure title.
""" """
fig, axes = plt.subplots(3, 1) fig, axes = plt.subplots(3, 1, layout="constrained")
self.plot_port_accesses(axes) self.plot_port_accesses(axes)
if title: if title:
fig.suptitle(title) fig.suptitle(title)
......
...@@ -18,7 +18,6 @@ from matplotlib.lines import Line2D ...@@ -18,7 +18,6 @@ from matplotlib.lines import Line2D
from matplotlib.patches import PathPatch, Polygon from matplotlib.patches import PathPatch, Polygon
from matplotlib.path import Path from matplotlib.path import Path
from matplotlib.ticker import MaxNLocator from matplotlib.ticker import MaxNLocator
from matplotlib.transforms import Bbox, TransformedBbox
from b_asic import Signal from b_asic import Signal
from b_asic._preferences import ( from b_asic._preferences import (
...@@ -1073,18 +1072,48 @@ class Schedule: ...@@ -1073,18 +1072,48 @@ class Schedule:
self.set_y_location(graph_id, i) self.set_y_location(graph_id, i)
for graph_id in self._start_times: for graph_id in self._start_times:
op = cast(Operation, self._sfg.find_by_id(graph_id)) op = cast(Operation, self._sfg.find_by_id(graph_id))
# Position Outputs adjacent to the operation generating them
if isinstance(op, Output): if isinstance(op, Output):
self.move_y_location( gen_op: Operation = op.preceding_operations[0]
graph_id, if (
self.get_y_location(op.preceding_operations[0].graph_id) + 1, gen_op.output_count == 1
True, or op.input(0).signals[0].source.index >= gen_op.output_count / 2
) ):
# Single output operation generating or lower half of outputs
# Put below
self.move_y_location(
graph_id,
self.get_y_location(gen_op.graph_id) + 1,
True,
)
else:
# Put above
self.move_y_location(
graph_id,
self.get_y_location(gen_op.graph_id),
True,
)
# Position DontCares adjacent to the operation using them
if isinstance(op, DontCare): if isinstance(op, DontCare):
self.move_y_location( source_op: Operation = op.subsequent_operations[0]
graph_id, if (
self.get_y_location(op.subsequent_operations[0].graph_id), source_op.input_count == 1
True, or op.output(0).signals[0].destination.index
) < gen_op.input_count / 2
):
# For single input operation consuming or upper half, position above
self.move_y_location(
graph_id,
self.get_y_location(source_op.graph_id),
True,
)
else:
# Position below
self.move_y_location(
graph_id,
self.get_y_location(source_op.graph_id),
True,
)
def _plot_schedule(self, ax: Axes, operation_gap: float = OPERATION_GAP) -> None: def _plot_schedule(self, ax: Axes, operation_gap: float = OPERATION_GAP) -> None:
"""Draw the schedule.""" """Draw the schedule."""
...@@ -1192,12 +1221,10 @@ class Schedule: ...@@ -1192,12 +1221,10 @@ class Schedule:
y = np.array(_y) y = np.array(_y)
xvalues = x + op_start_time xvalues = x + op_start_time
xy = np.stack((xvalues, y + y_pos)) xy = np.stack((xvalues, y + y_pos))
p = ax.add_patch(Polygon(xy.T, fc=_LATENCY_COLOR)) ax.add_patch(Polygon(xy.T, fc=_LATENCY_COLOR))
p.set_clip_box(TransformedBbox(Bbox([[0, 0], [1, 1]]), ax.transAxes))
if any(xvalues > self.schedule_time) and not isinstance(operation, Output): if any(xvalues > self.schedule_time) and not isinstance(operation, Output):
xy = np.stack((xvalues - self.schedule_time, y + y_pos)) xy = np.stack((xvalues - self.schedule_time, y + y_pos))
p = ax.add_patch(Polygon(xy.T, fc=_LATENCY_COLOR)) ax.add_patch(Polygon(xy.T, fc=_LATENCY_COLOR))
p.set_clip_box(TransformedBbox(Bbox([[0, 0], [1, 1]]), ax.transAxes))
if isinstance(operation, Input): if isinstance(operation, Input):
ax.annotate( ax.annotate(
graph_id, graph_id,
...@@ -1271,7 +1298,7 @@ class Schedule: ...@@ -1271,7 +1298,7 @@ class Schedule:
+ 1 + 1
+ (OPERATION_GAP if operation_gap is None else operation_gap) + (OPERATION_GAP if operation_gap is None else operation_gap)
) )
ax.axis([-1, self._schedule_time + 1, y_position_max, 0]) # Inverted y-axis ax.axis([-0.8, self._schedule_time + 0.8, y_position_max, 0]) # Inverted y-axis
ax.xaxis.set_major_locator(MaxNLocator(integer=True, min_n_ticks=1)) ax.xaxis.set_major_locator(MaxNLocator(integer=True, min_n_ticks=1))
ax.axvline( ax.axvline(
0, 0,
...@@ -1335,8 +1362,8 @@ class Schedule: ...@@ -1335,8 +1362,8 @@ class Schedule:
------- -------
The Matplotlib Figure. The Matplotlib Figure.
""" """
height = len(self._start_times) * 0.3 + 2 height = len(self._start_times) * 0.3 + 0.7
fig, ax = plt.subplots(figsize=(12, height)) fig, ax = plt.subplots(figsize=(12, height), layout="constrained")
self._plot_schedule(ax, operation_gap=operation_gap) self._plot_schedule(ax, operation_gap=operation_gap)
return fig return fig
...@@ -1345,8 +1372,8 @@ class Schedule: ...@@ -1345,8 +1372,8 @@ class Schedule:
Generate an SVG of the schedule. This is automatically displayed in e.g. Generate an SVG of the schedule. This is automatically displayed in e.g.
Jupyter Qt console. Jupyter Qt console.
""" """
height = len(self._start_times) * 0.3 + 2 height = len(self._start_times) * 0.3 + 0.7
fig, ax = plt.subplots(figsize=(12, height)) fig, ax = plt.subplots(figsize=(12, height), layout="constrained")
self._plot_schedule(ax) self._plot_schedule(ax)
buffer = io.StringIO() buffer = io.StringIO()
fig.savefig(buffer, format="svg") fig.savefig(buffer, format="svg")
......
...@@ -28,35 +28,35 @@ sfg ...@@ -28,35 +28,35 @@ sfg
# %% # %%
# Create an ASAP schedule for reference. # Create an ASAP schedule for reference.
schedule = Schedule(sfg, scheduler=ASAPScheduler()) schedule1 = Schedule(sfg, scheduler=ASAPScheduler())
schedule.show() schedule1.show()
# %% # %%
# Create an ALAP schedule for reference. # Create an ALAP schedule for reference.
schedule = Schedule(sfg, scheduler=ALAPScheduler()) schedule2 = Schedule(sfg, scheduler=ALAPScheduler())
schedule.show() schedule2.show()
# %% # %%
# Create a resource restricted schedule. # Create a resource restricted schedule.
schedule = Schedule(sfg, scheduler=HybridScheduler()) schedule3 = Schedule(sfg, scheduler=HybridScheduler())
schedule.show() schedule3.show()
# %% # %%
# Create another schedule with shorter scheduling time by enabling cyclic. # Create another schedule with shorter scheduling time by enabling cyclic.
schedule = Schedule( schedule4 = Schedule(
sfg, sfg,
scheduler=HybridScheduler(), scheduler=HybridScheduler(),
schedule_time=49, schedule_time=49,
cyclic=True, cyclic=True,
) )
schedule.show() schedule4.show()
# %% # %%
# Push the schedule time to the rate limit for one MADS operator. # Push the schedule time to the rate limit for one MADS operator.
schedule = Schedule( schedule5 = Schedule(
sfg, sfg,
scheduler=HybridScheduler(), scheduler=HybridScheduler(),
schedule_time=15, schedule_time=15,
cyclic=True, cyclic=True,
) )
schedule.show() schedule5.show()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment