Hello together, i am currently working on reaction path diagrams for N with cantera 2.2.1 for python 3.4. I have a very hard time styling them to my needs. For example, I would like to have the edges black instead of blue. diagram = ct.ReactionPath

296 views
Skip to first unread message

Tilman Bremer

unread,
Mar 6, 2017, 11:43:23 AM3/6/17
to Cantera Users' Group
Hello together,

i am currently working on reaction path diagrams for N with cantera 2.2.1 for python 3.4. I have a very hard time styling them to my needs. For example, I would like to have the edges black instead of blue.

diagram = ct.ReactionPathDiagram(gas, element)
diagram
.bold_color='black'
diagram
.normal_color='black'
diagram
.dashed_color='black'

seems to do nothing. Tried differnt colors, html color notation, too.

I tried to set it directly in the command line for dot:

os.system('dot {0} -Ecolor=black -Gcolor=black -Ncolor=black -Tpdf -o{1} -Gdpi=150'.format(dot_file, img_file))

I tried color schemes, because for the edges cantera seemed to need color variations:

os.system('dot {0} -Ecolor=greys5 -Gcolor=greys5 -Ncolor=greys5 -Tpdf -o{1} -Gdpi=150'.format(dot_file, img_file))

greys5 is from the Brewer Color Schemes, dot should support it (http://www.graphviz.org/content/color-names).

You guessed it: Nothing.

I also tried

diagram = ct.ReactionPathDiagram(gas, element)
diagram.dot_options='color=black;'

There are only two options for me right now, opening the .dot file and fumbling with it by hand, or opening the generated pdf with illustrator and setting colors by hand for all edges. Both tedious and ridiculous tasks.

Any help is appreciated. I feels like the people just stick with the regular color? I couldn't find any example or any question in this group around the coloring.

Minimal working example:
import os
import sys
import cantera as ct

gas = ct.Solution('gri30.xml')
gas.TPX = 1300.0, ct.one_atm, 'CH4:0.4, O2:1, N2:3.76'
r = ct.IdealGasReactor(gas)
net = ct.ReactorNet([r])
T = r.T
while T < 1900:
    net.step(1.0)
    T = r.T

element = 'N'

diagram = ct.ReactionPathDiagram(gas, element)
diagram.scale = -1
diagram.threshold = 5e-3

dot_file = 'test.dot'
img_file = 'test.pdf'
img_path = os.path.join(os.getcwd(), img_file)

diagram.write_dot(dot_file)
print(diagram.get_data())

print("Wrote graphviz input file to '{0}'.".format(os.path.join(os.getcwd(), dot_file)))

os.system('dot {0} -Ecolor=black -Gcolor=black -Ncolor=black -Tpdf -o{1} -Gdpi=150'.format(dot_file, img_file))
print("Wrote graphviz output file to '{0}'.".format(img_path))


Tilman Bremer

unread,
Mar 8, 2017, 4:53:29 PM3/8/17
to Cantera Users' Group
In the hope that someone might still be able answer my original question, I also would like to know how I erase the "Scale" label at the bottom of the diagram. I would like to add a note about the scale of the diagram in actual label in my master thesis. (Again, I could edit the .dot code by hand, but there must be a way to tell cantera to not include it?)

There are actually more questions about the reaction path diagrams, I am really trying to only include the ones that are the most pressing to me. And one that is: What is the unit of the flux? I tried to read all the docs and examples and it seems to me that there is no information about that at all.

Nick Curtis

unread,
Mar 9, 2017, 10:50:10 AM3/9/17
to Cantera Users' Group
Hi Tilman,
It looks like there are several things in the reaction path diagram that aren't actually hooked up to anything.
For instance, as you've found it appears that the colors


diagram.bold_color='black'
diagram
.normal_color='black'
diagram
.dashed_color='black'

don't get written to the output dotfile at any point.

However, the dot_options should be written to the file, see line 211.
It looks like the "normal" color could reasonably be patched in at line 282, although it would require some sort of mapping of color to hue.
The scale label is hardcoded in at line 366.
The flux is actually a log normalized ratio of the flux of a given path over the maximum flux over all paths, see for example line 254.

More generally, the ReactionPathDiagram isn't used too heavily as far as I'm aware, there is definitely room for improvements as you've found.
I would suggest the following; first if you wanted to add some of the features you needed directly to the C++ source (the python bindings that map this into C++ appear to be in place), a pull request on github would definitely be welcome.
However, in my experience getting a publication quality dot graph ready typically requires hand-styling no matter what you do.
Perhaps as an intermediate step, I would write a simple python script using regex that would read in the dot file and add/change the attributes you need (colors, label etc.).
I believe there are actually dot graph bindings for python as well, which may make your life easier.

Best,
Nick

Tilman Bremer

unread,
Mar 13, 2017, 1:57:24 PM3/13/17
to Cantera Users' Group
Hi Nick,

thank you very much for you answer. And sorry for my late response, I must have missed the notification.

I really didn't think about having a look into the source code. But thanks for pointing out the parts accordingly, some of the behavior of cantera is now much clearer to me, especially the scaling... I think that I going to do it like you suggested, writing some scripts to go over the .dot file and change the attributes. Like you say, the dot_options get written to the file, but all the hardcoded stuff actually lead to a lot of dot_options having no effect, e.g. colors.

Unfortunately, the unit of the flux is still not clear to me. As far as I understand it, the log normalization is only for linewidth of the arrows (line 272), for all printed values, it is a regular division by scale (flxratio). So when I provide a scale of 1, I should get the original value, which must have a unit? Is it maybe kmol/m^3/s? Found that in creation and destruction rates in the docs about kinetics.





Nick Curtis

unread,
Mar 15, 2017, 7:45:15 PM3/15/17
to Cantera Users' Group
Hi Tilman,
The fluxes themselves are indeed in kmol/m^3/s.  However, it appears that everything that gets output (arrow width, labels, etc.) are the ratio of the flux over the maximum flux (or scale if supplied).
You could recover the actual flux by multiplying by the Scale in the output by the value in the label (without show_details)

Nick
Reply all
Reply to author
Forward
0 new messages