Consider the "Custom styling" example in cell 11 in this link from the pytransitions github pages. (tweeked code below)
I would like to add a reset event. When Reset is triggered from most (but not all) other states the model returns to a known state. In this example that is INITIAL.
Doing this for a large digraph creates a lot of clutter, omitting it leads to lack of documentation.
The solution is to add a fake transition:
machine.add_transition("Reset", "* ANY_STATE *", "INITIAL")
So a 'fake' global state fixes the issue, and draws properly. It does not care the state is not defined.
However the styling code example uses the state key of the model but that does not exist as * ANY_STATE * is fake and not in the list of states.
How to style the dynamicaly added state?
Updated example:
class Model:
pass
model = Model()
transient_states = ['T1', 'T2', 'T3']
target_states = ['G1', 'G2']
fail_states = ['F1', 'F2']
transitions = [['eventA', 'INITIAL', 'T1'], ['eventB', 'INITIAL', 'T2'], ['eventC', 'INITIAL', 'T3'],
['success', ['T1', 'T2'], 'G1'], ['defered', 'T3', 'G2'], ['fallback', ['T1', 'T2'], 'T3'],
['error', ['T1', 'T2'], 'F1'], ['error', 'T3', 'F2']]
machine = GraphMachine(model, states=transient_states + target_states + fail_states,
transitions=transitions, initial='INITIAL', show_conditions=True,
use_pygraphviz=False, ## Jupyter does not work with pygraphviz ##
show_state_attributes=True)
machine.machine_attributes['ratio'] = '0.471'
machine.style_attributes['node']['fail'] = {'fillcolor': 'brown1'}
machine.style_attributes['node']['transient'] = {'fillcolor': 'gold'}
machine.style_attributes['node']['target'] = {'fillcolor': 'chartreuse'}
# **** EXTRA LINE ****
machine.add_transition("Reset", "* ANY_STATE *", "INITIAL")
# As before
model.eventC()
# customize node styling - NOTE: id(model) is the dict key
for s in transient_states:
machine.model_graphs[id(model)].set_node_style(s, 'transient')
for s in target_states:
machine.model_graphs[id(model)].set_node_style(s, 'target')
for s in fail_states:
machine.model_graphs[id(model)].set_node_style(s, 'fail')
# draw the whole graph ...
model.get_graph()

transitionswill just convert the machine's configuration into a graphviz diagram, either viapygraphvizorgraphviz. As you mentioned wildcard transitions may clutter a diagram. As you also figured out,transitionswill lazily evaluate source and destination states which allows you to add 'virtual' or as you called it 'fake' states. I'd guess at some point you want to actually call 'reset' which would not work with your current configuration. But this is not your question. So let's talk about how to edit the graph. As mentioned before, graphs are just decorated (py)graphviz diagrams under the hood. You can retrieve these diagrams withget_graphand edit them according to your liking. Whilegraphvizgraphs are rather simplistic,pygraphvizallows you to query nodes and edges. You need to refer to the documentation of graphviz or pygraphviz to figure out what they can provide and what suits you best.Adding a node configuration when it is not already defined is rather straight forward. Since you want to use
graphvizthis is how its done:This will result in a diagram like this: