Setting up and reusing Formats¶
During the implementation of the graph visualization processes, the aim was to create a system that is easy to use and reusable.
For this purpose, there is the Format class, which is explained and demonstrated in this notebook.
Instances of the Format class can be reused without being bound to a graph, similar to templates.
Creating a Format template¶
The Format class is defined inside the visualization package.
Execute the cell below to create a new instance and inspect it.
from netlist_carpentry.core.graph.visualization import Format
f = Format()
f.format_dict
{'formats': {}, 'labels': {}, 'node_formats': {}}
All formatting data is stored inside the Format.format_dict dictionary.
By default, the formatting dictionary is empty and only contains the category names:
formatswill contain the format definitions (a dictionary of format names and an associated format dictionary),labelsreceives a mapping of node names to labels (which will be used to display on top of the node),node_formatsis a mapping of node names to format names, so that each node of this dictionary is associated with a specific format name from theformatssection. Execute the cell below to create a format and apply it to a given node.
f.set_format("custom_format", node_color="#abcdef", node_size=420)
f.format_node("some_node", "custom_format")
f.format_dict
{'formats': {'custom_format': {'color': '#abcdef', 'size': 420}},
'labels': {},
'node_formats': {'some_node': 'custom_format'}}
Applying a defined Format¶
The defined format can be applied, e.g. when creating a Plotting instance.
Execute the cell below to read the design file as usual and set up the graph so that it can receive the defined format.
All formatting applied to the Plotting object will then also be found inside its format dict.
Also, the Format object can be accessed via Plotting.format.
import netlist_carpentry
from netlist_carpentry.core.graph.visualization import Plotting
FILE_PATH = "../files/decentral_mux.v"
circuit = netlist_carpentry.read(FILE_PATH, top="decentral_mux")
circuit.top.optimize()
GRAPH = circuit.top.graph()
plot = Plotting(GRAPH, format=f)
plot.format.format_dict # Identical to plot.format_dict
Instance building progress: 0%| | 0/96 [00:00<?, ?it/s]
{'formats': {'custom_format': {'color': '#abcdef', 'size': 420}},
'labels': {},
'node_formats': {'some_node': 'custom_format'}}
Afterwards, changes made to the Format object will directly affect the format of the Plotting object.
f.set_format("green_format", node_color='#00FF00')
f.format_node('SELECT_I', "green_format")
plot.format_dict
{'formats': {'custom_format': {'color': '#abcdef', 'size': 420},
'green_format': {'color': '#00FF00'}},
'labels': {},
'node_formats': {'some_node': 'custom_format', 'SELECT_I': 'green_format'}}
This also is the case vice versa. This is intended to make handling graph formatting and visualization both as easy and intuitive as possible.
plot.set_format("dark_blue", node_color="#0000AA")
plot.format_nodes(lambda node_name, data: "data" in node_name.lower(), format_name="dark_blue")
f.format_dict
{'formats': {'custom_format': {'color': '#abcdef', 'size': 420},
'green_format': {'color': '#00FF00'},
'dark_blue': {'color': '#0000AA'}},
'labels': {},
'node_formats': {'some_node': 'custom_format',
'SELECT_I': 'green_format',
'DATA_I': 'dark_blue',
'DATA_O': 'dark_blue'}}