evenly distribute pygraphviz nodes - graphviz

I have a graphviz code like this:
import pygraphviz as pgv
A = pgv.AGraph(strict=False, directed=True,
overlap=False, sep="+10,10")
[A.add_node(k) for k, v in S] # adding all nodes
A.add_edge(S.created, S.packaged_unassigned)
A.add_edge(S.packaged_unassigned, S.packaged_assigned)
A.add_edge(S.packaged_assigned, S.packaged_unassigned, style="dotted")
A.add_edge(S.packaged_assigned, S.shipped_to_distributor)
A.add_edge(S.shipped_to_distributor, S.on_distributor_side_out)
A.add_edge(S.on_distributor_side_out, S.shipped_to_deployer)
A.add_edge(S.shipped_to_deployer, S.on_distributor_side_in)
A.add_edge(S.on_distributor_side_in, S.shipped_to_lab)
A.add_edge(S.shipped_to_lab, S.on_lab_side)
A.add_edge(S.on_lab_side, S.analysis_completed)
A.add_edge(S.analysis_completed, S.completed)
A.layout()
A.draw("status_chart.png")
which produces this output:
https://i.ibb.co/7pJQ8rd/Screenshot-2020-12-20-at-22-23-10.png
My concern here is that the nodes seem to not utilize the available space properly. Instead they just span the diagonal of the image.
How can i make graphviz utilize the space better to create a smaller image while keeping the constraint of no overlaps?

One constraint is that you have specified a chained graph. and thus, the plot is somewhat constrained by that.
See the documentation for some possible alternative options to specify:
https://pygraphviz.github.io/documentation/latest/reference/agraph.html
For example, you can try specifying a landscape view
AGraph(landscape='true'...)
You can also try experimenting with different layout directives:
Optional prog=[‘neato’|’dot’|’twopi’|’circo’|’fdp’|’nop’] will use specified graphviz layout method.
Also see:
unflatten(args='')
To adjust directed graphs to improve layout aspect ratio.
Another technique you could use is to break-up parts of the graph, such that it might look like this (adding a text label to the nodes, with the numbering scheme):
(1) -> (2) ->(3)
(4) -> (5) ->(6)
...
NOTE: The Python documentation for that library specifically suggests that you also refer to the Graphviz documentation...for additional options.
http://www.graphviz.org/doc/info/lang.html
http://www.graphviz.org/doc/info/attrs.html
For example:
http://www.graphviz.org/doc/info/attrs.html#d:ratio
http://www.graphviz.org/doc/info/attrs.html#a:layout
http://www.graphviz.org/doc/info/attrs.html#d:scale
The Gallery also has some great examples, illustrating the use of different parameters
http://www.graphviz.org/gallery/

Related

Selection script for maya

I'm noob in script but good in animation, I need some help to create a script selection.
I found an exemple :
import maya.cmds as cmds
# Get selected objects
curSel = maya.cmds.ls(sl=True)
# Or, you can also specify a type in the listRelatives command
nurbsNodes = maya.cmds.listRelatives(curSel, allDescendents=True, noIntermediate=True, fullPath=True, type="nurbsCurve", path=True)
cmds.select(nurbsNodes)
But It doesn't select all the character's controlers...
I would like If I select a character controler curve or locator and I run the script, the result is all controls who can be keyed should be selected. Without the referenced character name.
Thanks a lot for the one who can help
Currently the listRelatives command is being used to list all child nodes under the currently selected transforms, whose type is a NURBS Curve, e.g. type="nurbsCurve". Typically all nodes in Maya inherit from some other node type (It's worth checking the nodes in Maya help -> technical documents ->nodes). Luckily locator nodes and curves both inherit from 'geometryShape', so you should be able to replace "nurbsCurve" with "geometryShape", and that will probably get you most of the way there. You may need to ignore certain returned nodes though - i.e. polygonal meshes you are using for rendering.

Aligning Clusters within Graphviz

I am using Graphviz to automatically create an architecture diagram. I am having the following two problems and was hoping to get assistance.
I am using UUID to uniquely identify a component (example: "a5320de8-a320-11ea-bb37-0242ac130002" [label="Component A"]). When mapping A -> B, I'll get "Component A" -> b0c5e47c. Which is strange. The only way that I've been able to map UUID to UUID is to put quotes around them. Any suggestions?
I want to align clusters in a specific manner and specific direction. I've tried {rank=same; cluster_B, cluster_C, cluster_D}; and "9653369c-a322-11ea-bb37-0242ac130002" -> "aa31adb9-9621-40c2-855c-621832dd8c61" [style=invis] But neither work.
I have three sections within my dot file, they are:
Components (within this section, I list out all 100+ components and color code them based on a specific rule.
Clusters (within this section, I cluster the components into specific 'groupings')
Diagram or mapping (within this section, I then map the different components and clusters).
Here is a sample of my DOT file.
digraph architecture {
#graph [rankdir=LR]
compound=true;
#Compliant
node[fillcolor="#013220" style="filled" shape=square fontcolor="white"];
"a5320de8-a320-11ea-bb37-0242ac130002" [label="Component A"]
"b0c5e47c-a320-11ea-bb37-0242ac130002" [label="Component B"]
#Clusters
#Customer-facing client application cluster
subgraph cluster_A{
label="Client Apps";
"f7b3915d-6b3d-4d4c-bef0-bdabda915c03";
"9912de2b-739a-4c5c-834e-e0c3d09d70d1";
"16bb2066-9293-470e-99ec-c59d8426c0ab";
"641a6601-f4f6-4c06-baa6-e5e232f8abed";
"c5e92b09-a470-4fb6-af5c-e5f7dbeff919";
}
#Diagrams
"f7b3915d-6b3d-4d4c-bef0-bdabda915c03" -> {"35305026-d285-458c-85ad-7eae4e785e84", "76e0e679-42a6-47f0-9164-abc223da07fe"};
76e0e679-42a6-47f0-9164-abc223da07fe" -> "35305026-d285-458c-85ad-7eae4e785108";
}
I get something like:
However, I want to arrange the cluster is a specific way, like:
As you found out, hyphens are not legal characters in a node ID unless the string is quoted. If you want more info: https://www.graphviz.org/doc/info/lang.html
There is no straight-forward to align clusters. Sometime you can force desired alignment by embedding multiple clusters within another cluster to "shrink-wrap" them. For example embed B3 and B4 within cluster B34. But no guarantees.
You can use gvpr to reposition clusters (and their contents) but that can get pretty complex.

Clustering using Representatives (CURE)

I need a numerical example which demonstrates the working of clustering using CURE algorithm.
https://www.cs.ucsb.edu/~veronika/MAE/summary_CURE_01guha.pdf
The pyclustering library has a number of clustering algorithims with examples, and example code on their Github. Here is a link the CURE example.
Googling Cure algorithim example also came up with a fair bit.
Hopefully that helps!
Using pyclustering library you can extract information about representatives points and means using corresponding methods (link to CURE pyclustering generated documentation):
# create instance of the algorithm
cure_instance = cure(<algorithm parameters>);
# start processing
cure_instance.process();
# get allocated clusteres
clusters = cure_instance.get_clusters();
# get representative points
representative = cure_instance.get_representors();
Also you can modify source code of the CURE algorithm to display changes after each step, for example, print them to console or even visualize. Here is an example how to modify code to display changes on each step clustering (after line 219) where star means representative point, small points - points itself and big points - means:
# New cluster and updated clusters should relocated in queue
self.__insert_cluster(merged_cluster);
for item in cluster_relocation_requests:
self.__relocate_cluster(item);
#
# ADD FOLLOWING PEACE OF CODE TO DISPLAY CHANGES ON EACH STEP
#
temp_clusters = [ cure_cluster_unit.indexes for cure_cluster_unit in self.__queue ];
temp_representors = [ cure_cluster_unit.rep for cure_cluster_unit in self.__queue ];
temp_means = [ cure_cluster_unit.mean for cure_cluster_unit in self.__queue ];
visualizer = cluster_visualizer();
visualizer.append_clusters(temp_clusters, self.__pointer_data);
for cluster_index in range(len(temp_clusters)):
visualizer.append_cluster_attribute(0, cluster_index, temp_representors[cluster_index], '*', 7);
visualizer.append_cluster_attribute(0, cluster_index, [ temp_means[cluster_index] ], 'o');
visualizer.show();
You will see sequence of images, something like that:
Thus, you can display any information that you need.
Also I would like to add that you can use C++ implementation of the algorithm for visualization (that is also part of pyclustering): https://github.com/annoviko/pyclustering/blob/master/ccore/src/cluster/cure.cpp

Extending sphinx.ext.graphviz with additional extension

I would like to extend the built-in sphinx-doc extension sphinx.ext.graphviz with a few featues. As the features are very special for my use case i do not want to extend sphinx.ext.graphviz itself.
Essentially i just want to (graphviz sources for reference)
parse with graphviz to get the graphviz nodes (~ Graphviz.run()),
modify the graphviz dotcode of the nodes (~ node['code'] = dotcode),
output/render (html/pdf) with graphviz without modification (~ e.g. for
html: html_visit_graphviz() -> render_dot_html()).
I have read the sphinx-doc extension developer guide but do not fully
understand the build phases/procedure and how to "combine" extensions like described above.
Is it possible to modifiy the inlined graphviz code between "Build Phase
1: Reading" and "Build Phase 3: Resolving" somehow using an additional
sphinx extension which "invokes" sphinx.ext.graphviz?
The solution provided by a sphinx-doc contributor [https://github.com/sphinx-doc/sphinx/issues/2246]:
Maybe you can do it with following code:
def on_doctree_read(app, doctree):
for node in doctree.traverse(graphviz):
code = re.sub('\];', ', color = red];', node['code']) # change color of nodes and edges
node['code'] = code
def setup(app):
app.connect('doctree-read', on_doctree_read)
In this example, I used the doctree-read event. It is raised at Reading phase. In more detail, you can see what is "Sphinx core events" at http://www.sphinx-doc.org/en/stable/extdev/appapi.html#sphinx-core-events

R: Which heatmap/image to get row-sorted plot without any dendrogram?

Which package is best for a heatmap/image with sorting on rows only, but don't show any dendrogram or other visual clutter (just a 2D colored grid with automatic named labels on both axes). I don't need fancy clustering beyond basic numeric sorting. The data is a 39x10 table of numerics in the range (0,0.21) which I want to visualize.
I searched SO (see this) and the R sites, and tried a few out. Check out R Graphical Manual to see an excellent searchable list of screenshots and corresponding packages.
The range of packages is confusing - which one is the preferred heatmap (like ggplot2 is for most other plotting)? Here is what I found out so far:
base::image - bad, no name labels on axes, no sorting/clustering
base::heatmap - options are far less intelligible than the following:
pheatmap::pheatmap - fantastic but can't seem to turn off the
dendrograms? (any hacks?)
ggplot2 people use geom_tile, as Andrie points out
gplots::heatmap.2 , ref - seems
to be favored by biotech people, but way overkill for my purposes. (no
relation to ggplot* or Prof Wickham)
plotrix::color2D.matplot also exists
base::heatmap is annoying, even with args heatmap(..., Colv=NA, keep.dendro=FALSE) it still plots the unwanted dendrogram on rows.
For now I'm going with pheatmap(..., cluster_cols=FALSE, cluster_rows=FALSE) and manually presorting my table, like this guy: Order of rows in heatmap?
Addendum: to display the value inside each cell, see: display a matrix, including the values, as a heatmap . I didn't need that but it's nice-to-have.
With pheatmap you can use options treeheight_row and treeheight_col and set these to 0.
just another option you have not mentioned...package bipartite as it is as simple as you say
library(bipartite)
mat<-matrix(c(1,2,3,1,2,3,1,2,3),byrow=TRUE,nrow=3)
rownames(mat)<-c("a","b","c")
colnames(mat)<-c("a","b","c")
visweb(mat,type="nested")

Resources