Graphviz how to separate nodes equally (possibly with nodesep)? - position

I am making a graph using dot that splits into 4 parallel rows with links between them (see code below). I have organised the starting nodes into a subgraph using rank=same to ensure they start in line vertically, and then used edge[weight] to ensure each row is a straight horizontal line.
Due to the links between the rows, the initial nodes are unequally spaced vertically. Is there a way of setting them to be equal distance (i.e. increasing the distance between rows C,D,E to match the distance between B,C)? I have tried using nodesep in the subgraph but there is no effect. Any ideas? Thanks
graph Example {
rankdir=LR
ordering=out
{ rank=same
b1
c1
d1
e1
}
a1--b1
a1--c1
a1--a2--d1
a2--e1
edge[weight=100]
b1--b2--b3--b4
c1--c2--c3--c4
d1--d2--d3--d4
e1--e2--e3--e4
edge[weight=1]
b1--bc--c3
}

This may be a case for invisible nodes (and edges...).
Just add some invisible nodes between the rank=same subgraph to force exactly one node between the lines:
graph Example {
rankdir=LR
ordering=out
{ rank=same
b1 [group=b]
c1 [group=c]
d1 [group=d]
e1 [group=e]
// invisible nodes
node[style=invis]
edge[style=invis]
b1--i1--c1--i2--d1--i3--e1
}
node [group=b]
b1--b2--b3--b4
node [group=c]
c1--c2--c3--c4
node [group=d]
d1--d2--d3--d4
node [group=e]
e1--e2--e3--e4
node[group=""]
a1--b1
a1--c1
a1--a2--d1
a2--e1
b1--bc--c3
}
I also used groups to suggest straight lines instead of weight.

What you are (I think) trying to achieve is the default behavior of graphviz/dot. I think if you remove all "steering" in your graph, you'll get exactly what you need. At least in the below graph, nodes are vertically evenly distributed on each "rank".
graph Example {
rankdir=LR
ordering=out
a1--b1
a1--c1
a1--a2--d1
a2--e1
b1--b2--b3--b4
c1--c2--c3--c4
d1--d2--d3--d4
e1--e2--e3--e4
b1--bc--c3
}

Related

R DiagrammeR package Mermaid text using actual calculation results

I would like to utilize the DiagrammeR package for a simple flow chart in my Rmarkdown. However, I couldn't figure out a way to use actual output from a data table into the text. Suppose I have a simple query of a database with total records, patients count and date in year info for three different cohorts.
I wanted to create a diagram using Mermaid. The codes look at this.
Total = paste0('Records:',b1$records,' Patients:',b1$patients,' Year:',b1$year)
# (Records:1000 Patients:822 Year:5)
Sub1 = paste0('Records:',b2$records,' Patients:',b2$patients,' Year:',b2$year)
Sub2 = paste0('Records:',b3$records,' Patients:',b3$patients,' Year:',b3$year)
mermaid("
graph TB
A[Total] --> B{Sub1} --> C{Sub2}
")
Instead of Printing out diagram with: Records:1000 Patients:822 Year:5 in the A, it shows verbatim word "Total".
Any suggestion on how to do it correctly?
Thanks!
You are one step away from what you'd like to achieve. Please try this simple example below to see the logic:
library(DiagrammeR)
Stracture:
DiagrammeR(
"
graph TB
A[Question] -->B[Answer]
"
)
1. Define answer node:
B <- paste0("There are ", nrow(iris), " records")
2. Combine it with other components, using ; to separate statements:
results <- paste0("graph TB; A[How many rows does iris have?]-->", "B[", B, "]")
3. Call 'results' in DiagrammeR:
DiagrammeR(diagram = results)
The final plot should refresh when your calculation updates.
The plot that calls your calculation

graphviz: is there a way to display only a subset of the subgraphs I have defined or have a B&W version(disable colors)?

are they easy ways
to display only a subset of the subgraphs I have defined without commenting or else?
to disable all colors/have a black and white version of the graph
thanks
P.S: it is for teaching/presentation purpose
The layers feature (https://graphviz.org/faq/#FaqOverlays) is the "best" way to produce a subset graph. But there are severl oddities in the implementation (e.g. https://forum.graphviz.org/t/stupid-dot-tricks-2-making-a-video/109) that make it a bit of a pain. An example:
digraph CL {
graph [layers="A:C:D"]
subgraph cluster1{
node [layer="A,C,D"]
a->b->c->{e f}
}
subgraph cluster11{
node [layer="C,D"]
ax->bx->{cx ex fx}
}
subgraph cluster12{
node [layer="D"]
ay->{by cy ey fy}
}
subgraph clusterZAZ{
node [layer="A,D"]
a55->{b55 c55 e55 frrrr}
}
// comment out the next line and see what happens
edge [layer=D] // this should not be necessary
ax->by
}
Here is a command line to produce layer C:
dot -Tsvg -Glayerselect=C clusterLayers.gv >C.svg
Maybe Inkscape (https://inkscape.org/) convert a colored SVG graph to black-and-white

How to create a first derivative calculated column in spotfire

I am trying to use calculated columns in Spotfire to calculate the first derivative (x,y)for individual time series IDs (Z)
My data looks like this,
x,y,z
0,0,A
1,1,A
2,1.5,A
3,1,A
4,1,A
5,.9,A
6,.5,A
7,.1,A
8,1.1,A
9,11,A
1,1,B
2,1.5,B
3,1,B
4,1,B
5,.9,B
6,.5,B
7,.1,B
8,1.1,B
9,11,B
10,12,B
I was using this:
([y] - Min([y]) OVER (Previous([x])))
/
([x] - Min([x]) OVER (Previous([x])))
but (1) it doesn't seem right; and (2) how do i then do this OVER every [Z]
This should work:
([y] - min([y]) Over (Intersect([z],Previous([x])))) / ([x] - min([x]) Over (Intersect([z],Previous([x]))))
however the first point is going to be blank for each z, and it might not be very stable if your data has lots of oscillations. For more sophisticated options, you could look into splines (see a number of SO answers) and using a TERR function (not data function, the functions starting with TERR_ if they are available to you) for the calculated column.
Gaia

code produces a 2d histogram but the results dont match with hist2d

I am trying to write a histogram builder to construct a 2d histogram for my assignment work. This is [my code][1]:
def Build2DHistogramClassifier(X1,X2,T,B,x1min,x1max,x2min,x2max):
HF=np.zeros((B,B),dtype='int');#initialising a empty array of integer type
HM=np.zeros((B,B),dtype='int');
bin_row_indices=(np.round(((B-1)*(X1-x1min)/(x1max-x1min)))).astype('int32');"""this logic decides which bin the value goes into"""
bin_column_indices=(np.round(((B-1)*(X2-x2min)/(x2max-x2min)))).astype('int32');"""np.round-->applies the formula to all the values in the array"""
for i,(r,c) in enumerate(zip(bin_row_indices, bin_column_indices)):
"""enumerate-->if we put array or list into it gives output with index/count i """
if T[i]=='Female':
HF[r,c]+=1;
else:
HM[r,c]+=1;
return [HF, HM]
but the problem is that the results( count in each bin) i am getting is not matching the what i get from using hist2d function in numpy( i passed the same bin size)
i am sorry if my code is not in the right format. Please click on the hyperlink to a gist i created with the same code.
what is the mistake in my code?
how do i correct it?
thanks
By rounding when assigning to bins you are treating the bins as bin centers. The numpy convention is to use them as bin edges.
Remove the two calls to round() from your code and change B-1 to B. You should now get the same results with your function and with np.histogram2d.

In networkx 2.1, if a graph is assigned to a new empty graph and edges are removed from new graph why it is removing edge from old graph?

I have created a graph by merging 4 graphs by
WaterWayNWK=nx.from_pandas_edgelist(WaterWayUID,'Node-A','Node-B',['Distance'])
RoadNWK=nx.from_pandas_edgelist(Road_ODUID,'Node-A','Node-B',['Distance'])
RailNWK=nx.from_pandas_edgelist(RailUID,'Node-A','Node-B',['Distance'])
TerminalNWK=nx.from_pandas_edgelist(TerminalUID,'Node-A','Node-B',['Distance'])
Network_lst=[WaterWayNWK,RoadNWK,RailNWK,TerminalNWK]
SynchoromodalNWK=nx.compose_all(Network_lst)
then I am assigning this to an empty dummy graph
Dummy=nx.Graph()
Dummy=SynchoromodalNWK
finally, I am removing nodes from the new graph and calculating the number of edges in both.
print('before removal:',len(SynchoromodalNWK.edges()))
Dummy.remove_nodes_from(['RI3_1177', 'WI3_1177'])
print(len(Dummy.edges()))
print(len(SynchoromodalNWK.edges()))
output is coming as :-
runfile('C:/Users/NaVnEeT/Desktop/adj/untitled2.py',
wdir='C:/Users/NaVnEeT/Desktop/adj')
before removal: 2343
2339
2339
Why are the edges removed from original?
In Python variable names are bound to values.
Dummy=nx.Graph() binds the variable name Dummy to the value nx.Graph().
The assignment Dummy=SynchoromodalNWK rebinds Dummy to the value SynchoromodalNWK,
rendering the first assignment nugatory.
So after this assignment, Dummy is SynchoromodalNWK is True. Both variables, Dummy and SynchoromodalNWK are "bound to" (or you could say "refer to") the same value.
Modifying Dummy modifies SynchoromodalNWK.
If you want Dummy to be a copy of SynchoromodalNWK (so that modifying Dummy will not affect SynchoromodalNWK), use
Dummy = SynchoromodalNWK.copy()
Dummy=nx.Graph() is not necessary.

Categories

Resources