Graphviz cluster alignment - alignment

My graph has 5 clusters (1 vertical, 4 horizontal),
I want to correct three things here,
all horizontal clusters to be on the right side
every horizontal cluster to be on the same height with the node connected on the left cluster (no to be shifted above or under)
horizontal cluster nodes to order from 1 to 4 as defined in the clusters (not randomly)
I tried grouping and ranking yet couldn't manage to fix it,
digraph {
graph[bgcolor = '#FDFDFD']
node[fontname = 'helvetica-bold', width = 1.5, height = 0.5, fontsize=12]
rankdir=TB;
subgraph cluster_main {
style=dashed; color= '#625a5a';
label='Steps for \n Scientometric Analysis'
graph[rankdir=TB]
node [shape=box, style=filled, color=black,
fillcolor = '#91cf60'];
a[group=g1, label = 'Section 1 \n Descriptive Analysis']
b[group=g2, label = 'Section 2 \n Intellectual Structure']
c[label = 'Section 3 \n Historiograph']
d[group=g3, label = 'Section 4 \n Conceptual structure']
e[label = 'Section 5 \n Thematic Map']
f[group=g4, label = 'Section 6 \n Social structure']
a -> b -> c -> d -> e -> f}
subgraph cluster_a {
color= '#625a5a';
node [shape=box, style = filled, color=black,
fillcolor = '#fee08b'];
a4[group=g1, label = 'Top manuscripts']
a3[group=g1, label = 'Most Productive \n Authors']
a2[group=g1, label = 'Most Cited \n References']
a1[group=g1, label = 'Main findings']}
subgraph cluster_b {
color= '#625a5a';
node [shape=box, style = filled, color=black,
fillcolor = '#fee08b'];
b4[group=g2, label = 'Source \n coupling analysis']
b3[group=g2, label = 'Source \n co-citation analysis']
b2[group=g2, label = 'Article \n coupling analysis']
b1[group=g2, label = 'Article \n co-citation analysis']}
subgraph cluster_d {
color= '#625a5a';
node [shape=box, style = filled, color=black,
fillcolor = '#fee08b'];
d4[group=g3, label = 'Title & Abstract \n Term Analysis']
d3[group=g3,
label = 'Correspondence Analysis \n for both Keywords']
d2[group=g3,
label = 'Author Keyword \n Co-occurrence & Growth']
d1[group=g3,
label = 'Keyword-Plus \n Co-occurrence & Growth']}
subgraph cluster_f {
color= '#625a5a';
node [shape=box, style = filled, color=black,
fillcolor = '#fee08b'];
f4[group=g4, label = 'Country \n Collaboration Network']
f3[group=g4, label = 'Edu \n Collaboration Network']
f2[group=g4, label = 'Author \n Collaboration Network']
f1[group=g4, label = 'Three Fields \n Plots']}
a -> {a1 a2 a3 a4}
b -> {b1 b2 b3 b4}
d -> {d1 d2 d3 d4}
f -> {f1 f2 f3 f4}
edge[style=invis]
a1 -> b1 -> d1 -> f1
a2 -> b2 -> d2 -> f2
a3 -> b3 -> d3 -> f3
a4 -> b4 -> d4 -> f4
}

Clusters are hard to position. You were pretty close. I added a cluster around the 4 horizontal clusters to corral them, but that wasn't needed. And changed the groups. Look for the word "added" to find the changes.
digraph {
graph[bgcolor = "#FDFDFD"]
graph [newrank=true] // added
node[fontname = "helvetica-bold", width = 1.5, height = 0.5, fontsize=12]
rankdir=TB;
subgraph cluster_main {
style=dashed; color= "#625a5a";
label="Steps for \n Scientometric Analysis"
graph[rankdir=TB]
node [shape=box, style=filled, color=black, fillcolor = "#91cf60"];
node [group=vert] // added
a[label = "Section 1 \n Descriptive Analysis"]
b[label = "Section 2 \n Intellectual Structure"]
c[label = "Section 3 \n Historiograph"]
d[label = "Section 4 \n Conceptual structure"]
e[label = "Section 5 \n Thematic Map"]
f[label = "Section 6 \n Social structure"]
a -> b -> c -> d -> e -> f}
subgraph cluster_a {
color= "#625a5a";
node [shape=box, style = filled, color=black, fillcolor = "#fee08b"];
a4[label = "Top manuscripts"]
a3[label = "Most Productive \n Authors"]
a2[label = "Most Cited \n References"]
a1[label = "Main findings"]}
subgraph cluster_b {
color= "#625a5a";
node [shape=box, style = filled, color=black, fillcolor = "#fee08b"];
b4[label = "Source \n coupling analysis"]
b3[label = "Source \n co-citation analysis"]
b2[label = "Article \n coupling analysis"]
b1[label = "Article \n co-citation analysis"]}
subgraph cluster_d {
color= "#625a5a";
node [shape=box, style = filled, color=black, fillcolor = "#fee08b"];
d4[label = "Title & Abstract \n Term Analysis"]
d3[label = "Correspondence Analysis \n for both Keywords"]
d2[label = "Author Keyword \n Co-occurrence & Growth"]
d1[label = "Keyword-Plus \n Co-occurrence & Growth"]}
subgraph cluster_f {
color= "#625a5a";
node [shape=box, style = filled, color=black, fillcolor = "#fee08b"];
f4[label = "Country \n Collaboration Network"]
f3[label = "Edu \n Collaboration Network"]
f2[label = "Author \n Collaboration Network"]
f1[label = "Three Fields \n Plots"]
}
// added rank=same
{rank = same a -> {a1 a2 a3 a4} }
{rank = same b -> {b1 b2 b3 b4} }
{rank = same d -> {d1 d2 d3 d4} }
{rank = same f -> {f1 f2 f3 f4} }
edge[style=invis]
a1 -> b1 -> d1 -> f1
a2 -> b2 -> d2 -> f2
a3 -> b3 -> d3 -> f3
a4 -> b4 -> d4 -> f4
}
Giving:

Related

ggplotly tooltip is showing data twice

I have 2 datasets included in one chart using ggplot. I am using ggplotly to create a tooltip but the information in the tooltips for the 2 points is showing twice. The following code is a little lengthy but will recreate the chart:
AreaName <- c("A", "B", "C", "A", "B", "C")
Timeperiod <- c("2018", "2018", "2018", "2019", "2019", "2019")
Value <- c(11.5, 39.3, 9.4, 14.2, 40.7, 19.1)
df <- data.frame(cbind(AreaName, Timeperiod, Value), stringsAsFactors = F)
df$Value <- as.numeric(df$Value)
AreaName <- c("A", "A")
Timeperiod <- c("2019", "2020")
qtr <- c("Q1-Q2", "Q1-Q2")
Value <- c(15.6, 10.2)
df2 <- data.frame(cbind(Timeperiod, qtr, AreaName, Value), stringsAsFactors = F)
df2$Value <- as.numeric(df2$Value)
ggp <- ggplotly(ggplot(data = df, aes(x=Timeperiod, y=Value, group = AreaName, colour = AreaName, text = paste("Area name: ", AreaName, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000"))) +
geom_line() +
geom_point() +
geom_point(data = df2, aes(shape = c(paste(AreaName, qtr, Timeperiod)),text = paste("Area name: ", AreaName, "<br>Quarter: ", qtr, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000"))) +
scale_shape_manual(values = c(18, 17)) +
theme(axis.text.x = element_text(vjust = 0.5), axis.title.x = element_blank()) +
labs(y = "Crude rate per 100,000 persons all ages", colour = "Area", shape = "") +
guides(shape = guide_legend(order = 2),colour = guide_legend(order = 1)) +
expand_limits(y=0), tooltip = "text")
ggpNames <- unique(df$AreaName)
legs <- paste(df2$AreaName, df2$qtr, df2$Timeperiod)
ggpNames <- c(ggpNames,legs)
for (i in 1:length(ggp$x$data)) { # this goes over all places where legend values are stored
n1 <- ggp$x$data[[i]]$name # and this is how the value is stored in plotly
n2 <- " "
for (j in 1:length(ggpNames)) {
if (grepl(x = n1, pattern = ggpNames[j])) {n2 = ggpNames[j]} # if the plotly legend name contains the original value, replace it with the original value
}
ggp$x$data[[i]]$name <- n2 # now is the time for actual replacement
if (n2 == " ") {ggp$x$data[[i]]$showlegend = FALSE} # sometimes plotly adds to the legend values that we don't want, this is how to get rid of them, too
}
ggp %>% config(displaylogo = FALSE, modeBarButtonsToRemove = list("autoScale2d", "resetScale2d","select2d", "lasso2d", "zoomIn2d", "zoomOut2d", "toggleSpikelines", "zoom2d", "pan2d"))
ggp
Does anyone have an elegant solution to this?
Thanks
Do not define text in geom_point for the second dataframe df2. Then you will get only one tooltip for those two points.
ggp <- ggplotly(ggplot(data = df, aes(x=Timeperiod, y=Value, group = AreaName, colour = AreaName, text = paste("Area name: ", AreaName, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000"))) +
geom_line() +
geom_point() +
geom_point(data = df2, aes(shape = c(paste(AreaName, qtr, Timeperiod)) #,
#text = paste("Area name: ", AreaName, "<br>Quarter: ", qtr, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000")
)) +
scale_shape_manual(values = c(18, 17)) +
theme(axis.text.x = element_text(vjust = 0.5), axis.title.x = element_blank()) +
labs(y = "Crude rate per 100,000 persons all ages", colour = "Area", shape = "") +
guides(shape = guide_legend(order = 2),colour = guide_legend(order = 1)) +
expand_limits(y=0), tooltip = "text")
ggpNames <- unique(df$AreaName)
legs <- paste(df2$AreaName, df2$qtr, df2$Timeperiod)
ggpNames <- c(ggpNames,legs)
for (i in 1:length(ggp$x$data)) { # this goes over all places where legend values are stored
n1 <- ggp$x$data[[i]]$name # and this is how the value is stored in plotly
n2 <- " "
for (j in 1:length(ggpNames)) {
if (grepl(x = n1, pattern = ggpNames[j])) {n2 = ggpNames[j]} # if the plotly legend name contains the original value, replace it with the original value
}
ggp$x$data[[i]]$name <- n2 # now is the time for actual replacement
if (n2 == " ") {ggp$x$data[[i]]$showlegend = FALSE} # sometimes plotly adds to the legend values that we don't want, this is how to get rid of them, too
}
ggp %>% config(displaylogo = FALSE, modeBarButtonsToRemove = list("autoScale2d", "resetScale2d","select2d", "lasso2d", "zoomIn2d", "zoomOut2d", "toggleSpikelines", "zoom2d", "pan2d"))
ggp

Need DXL code to arrange attribute lines into table (converting DOORS data to LaTeX source)

I have a DXL script which parses all data in DOORS columns into a LaTeX -compatible text source file. What I can't figure out is how to re-order some data into a tabular - compatible format. The attributes in question are DXL links to a reference DOORS module, so there is one line (separated by a line-feed) per link in each cell. Currently I loop thru all columns for each object (row), with the code snippet (part of the full script)
for col in doorsModule do {
var_name = title( col )
if( ! main( col ) && search( regexp "Absolute Number", var_name, 0 ) == false )
{
// oss is my output stream variable
if ( length(text(col, obj) ) > 0 )
{
oss << "\\textbf{";
oss << var_name; // still the column title here
oss << "}\t"
var_name = text( col, obj );
oss << var_name;
oss << "\n\n";
c++;
}
}
}
Examples of the contents of a cell, where I have separately parsed the Column Name to bold and collected it prior to collecting the cell contents. All four lines are the contents of a single cell.
\textbf{LinkedItemName}
DISTANCE
MinSpeed
MaxSpeed
Time
\textbf{Unit}
m
km/h
km/h
minutes
\textbf{Driver1}
100
30
80
20
\textbf{Driver2}
50
20
60
10
\textbf{Driver3}
60
30
60
30
What I want to do is re-arrange the data so that I can write the source code for a table, to wit:
\textbf{LinkedItemName} & \textbf{Unit} & \textbf{Driver1} & \textbf{Driver2} & \textbf{Driver3} \\
DISTANCE & m & 100 & 50 & 60 \\
MinSpeed & km/h & 30 & 20 & 30 \\
MaxSpeed & km/h & 80 & 60 & 60 \\
Time & minutes & 20 & 10 & 30 \\
I know in advance the exact Attribute names I'm "collecting." I can't figure out how to manipulate the data returned from each cell (regex or otherwise) to create my desired final output. I'm guessing some regex code (in DXL) might be able to assign the contents of each line within a cell to a series of variables, but don't quite see how.
Combination of regex and string assembly seems to work. Here's a sample bit of code (some of which is straight from the DOORS DXL Reference Manual)
int idx = 0
Array thewords = create(1,1)
Array thelen = create(1,1)
Regexp getaline = regexp2 ".*"
// matches any character except newline
string txt1 = "line 1\nline two\nline three\n"
// 3 line string
while (!null txt1 && getaline txt1) {
int ilen = length(txt1[match 0])
print "ilen is " ilen "\n"
put(thelen, ilen, idx, 0)
putString(thewords,txt1[match 0],0,idx)
idx ++
// match 0 is whole of match
txt1 = txt1[end 0 + 2:] // move past newline
}
int jj
// initialize to simplify adding the "&"
int lenone = (int get(thelen,0,0) )
string foo = (string get(thewords, 0, 0,lenone ) )
int lenout
for (jj = 1; jj < idx; jj++) {
lenout = (int get(thelen,jj,0) )
foo = foo "&" (string get(thewords, 0, jj,lenout ) )
}
foo = foo "\\\\"
// foo is now "line 1&line two&line three\\ " (without quotes) as LaTeX wants

horizontal alternative columns with transpose

Transposing rows in alternate columns
Suppose I have a continuous row
A1 = 1 A2 = 2 A3 = 3 A4 = $
I need to transpose it to
B1 = 1 D1 = 2 F1 = 3 H1 = 4
Is it possible?
=TRANSPOSE({A1; ""; A2; ""; A3; ""; A4})
={A1, "", A2, "", A3, "", A4}
if you are not US localized use: ={A1\ ""\ A2\ ""\ A3\ ""\ A4}
Try:
=if(isodd(column()),"",OFFSET($A1,int(column()-2)/2,))
in B1 and copy across to the right (assuming LTR).

Latex: Why are these sections indented too much?

I am writing a latex document with chapters and sections, but sections are indenting like subsections. At the risk of boring you, here is the code. I've tried to include a minimal verifiable example, but I may have missed something.
\chapter{In the begin there was Euclid}
\section{Greatest Common Divisor}
And some things.
\begin{lstlisting}
func GCD(a int32, b int32) int32 {
var u int32
var v int32
var t int32
var x int32
if a < 0 && a < -math.MaxInt32 {
fmt.Println("GCD: integer overflow")
a = -a
}
if b < 0 && b < -math.MaxInt32 {
fmt.Println("GCD: integer overflow")
b = -b
}
if b == 0 {
x = a
} else {
u = a
v = b
for v != 0 {
t = u % v
u = v
v = t
}
x = u
}
return x
}
\end{lstlisting}
And more.
\section{Section 2}
And some stuff.
\begin{lstlisting}
func XGCD(a int32, b int32) (int32, int32, int32) {
var u, v, u0, v0, u1, v1, u2, v2, q, r int32
var aneg, bneg int32
if a < 0 {
if a < -math.MaxInt32 {
fmt.Println("XGCD: integer overflow")
}
a = -a
aneg = 1
}
if b < 0 {
if b < -math.MaxInt32 {
fmt.Println("XGCD: integer overflow")
}
b = -b
bneg = 1
}
u1 = 1
v1 = 0
u2 = 0
v2 = 1
u = a
v = b
for v != 0 {
q = u / v
r = u % v
u = v
v = r
u0 = u2
v0 = v2
u2 = u1 - q*u2
v2 = v1 - q*v2
u1 = u0
v1 = v0
}
if aneg != 0 {
u1 = -u1
}
if bneg != 0 {
v1 = -v1
}
return u, u1, v1
}
\end{lstlisting}
The problem is that the second section always indents too far as if it's a subsection of the first. Here's a picture (the red text was added after taking the screen shot).
I'm thinking it has something to do with the page break.
The page is being included in the following document.
\documentclass[a4paper,twoside]{scrbook}
\usepackage{amsmath,amsthm,verbatim,amssymb,amsfonts,amscd, graphicx, listings}
\usepackage{graphics}
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\newtheorem{corollary}{Corollary}
\newtheorem{lemma}{Lemma}
\newtheorem{proposition}{Proposition}
\newtheorem*{surfacecor}{Corollary 1}
\newtheorem{conjecture}{Conjecture}
\newtheorem{question}{Question}
\theoremstyle{definition}
\newtheorem{definition}{Definition}
\begin{document}
\title{Number Theory and Abstract Algebra for Programmers}
\author{Kilgore Trout}
\frontmatter
\maketitle
\tableofcontents
\mainmatter
\include{introduction}
\include{in_the_beginning_there_was_euclid}
\include{and_then_there_were_groups}
\end{document}
I tried removing all of the packages and to minimize the whole thing, but nothing worked. Is there a problem with lstlisting spanning pages? Did I miss a closing statement somewhere? Why is the page 4 indented so far?
UPDATE: I don't think it's the page break causing the problem. I added a \clearpage before the new section and it was still nested with the previous section.
This is normal behavior for the Book document type.
Left pages have a supplementary margin on the left while right pages have this supplementary margin on the right. These margins are here for sidenotes. (Folk's like Fermat make important use of these...)
Your second section happens to be on the second page, that explain the margin your seeing.
For more details about the book class margins have a look at this answer.

Score calculation for two different teams

How would i go about counting the scores between C1 and C8 and entering the values into A2 and B2?
a1 = blue
b1 = red
a2 = team blue score
b2 = team red score
between c1 to c8 = winning team & score (NOTE: c1 = $a$1&" 1.25" )
c1 = blue 1.25
c2 = blue 2
c3 = red .5
c4 = draw
c5 = blue 1.5
c6 = blue 1.75
c7 = red 2
c8 = draw
So what I should get is:
A2 should = 6.5
B2 should = 2.5
You can get the total score of the blue team with
=sum(arrayformula(if(left(C1:C, 4)="blue", value(regexreplace(C1:C, "[^0-9.]", "")), 0)))
For the red team, use left(C1:C, 3)="red" in the formula.
The conversion from text to number happens in two steps: regexreplace removes all characters except . and 0-9; then value converts text to number.
It would be better to keep the winning team and their score in separate cells (team in column C, their score in column D), which would simplify the handling of this data: you'd only need =sumif(C1:C, "blue", D1:D).
Taking help of helper columns and without Array formula.These formula can adapt if you change team to Green or any other colour.
Formula in D1:(And Fill down)
=VALUE(RIGHT(C1,(LEN(C1)-LEN($A$1))))
Formula in E1:((And Fill down)
=LEFT(C1,(MIN(FIND({0,1,2,3,4,5,6,7,8,9},C1&"0123456789"))-2))
(And Fill down)
Formula in A2:
=SUMIF(E1:E9,"blue",D1:D9)
Formula in B2:
=SUMIF(E1:E9,"red",D1:D9)

Resources