【问题标题】:Is there a tool for drawing diagrams that connect equations?是否有用于绘制连接方程式的图表的工具?
【发布时间】:2020-08-01 18:57:03
【问题描述】:

其实我不知道怎么问这个问题。但我有一堆方程和常数,并且都以某种方式连接起来。比如说Matlab中的如下代码:

R=8.314;
n=0.412;
a=4;
m=2;
S=10;
rho=1;
F=m*a;
P=F/S;
V=m/rho;
T=(P*V)/(n*R);

有没有一种方法可以让 Matlab(或其他语言)返回一个带有工作流的图表,或者类似的东西?

因为我认为任何语言都需要按顺序定义每个常数和方程,所以我只想恢复那个顺序

【问题讨论】:

  • 欢迎来到 Stack Overflow。这是一个很好的问题。我还没有看到有人构建它,但它将是教授“编程入门”课程的绝佳工具。
  • 像 MATLAB 这样的解释器不会在内部构建这样的图。相反,每一行代码都会依次执行。如果在执行时,一行引用了一个不存在的变量,程序就会出错。因此,在精神上可能会制作这样一个图表的是程序员,而不是解释器。另一方面,优化编译器(例如 C 或 C++ 的编译器)将在内部构建这样的图,作为用于优化操作顺序的代码分析的一部分,并找到不适合的冗余操作根本需要执行,因为结果没有被使用。

标签: r matlab workflow diagram flowchart


【解决方案1】:

在 R 中使用 igraph 包,如图所示。我们假设输入的是末尾注释中显示的字符串Lines

使用scan 读取输入(scan 也可以从文件中读取,但为了保持内容自包含,我们在此处使用字符串作为输入),删除空组件并去除空格。

提取每行的 lhs 和 rhs。

然后对于rhs 的每个元素,获取其中的变量,给出列表 L。用变量 = 表达式形式的字符标签替换名称。

转换为数据框,然后转换为 igraph 对象g 并绘图。

library(igraph)
set.seed(123)

V1 <- scan(text = Lines, sep = ";", what = "", quiet = TRUE)
V1 <- gsub(" ", "", V1[V1 != ""])

lhs <- sub("=.*", "", V1)
rhs <- sub(".*=", "", V1)

L <- setNames(lapply(rhs, function(x) all.vars(parse(text = x))), V1)
L <- lapply(L, function(x) ifelse(x %in% lhs, 
  paste0(x, "=", rhs[match(x, lhs)]), x))

g <- graph.data.frame(stack(L))
plot(g, vertex.color = NA, vertex.frame.color = NA)

热图

另一种可能的表示形式是热图。获取邻接矩阵,可选地删除全为零的行和列并绘制。

m <- as.matrix(get.adjacency(g))
m <- m[apply(m > 0, 1, any), apply(m > 0, 2, any)] # rm 0 rows & cols
heatmap(m, Rowv = NA, Colv = NA, col = 2:3, scale = "none", 
  margins = c(7, 7), cexCol = 1, cexRow = 1)

气泡图

类似于热图,我们可以绘制气泡图:

library(ggplot2)
ggplot(stack(L), aes(ind, values)) + geom_point(cex = 10) + xlab("") + ylab("")

文字

另一种可能性是仅使用文本显示依赖关系。如果您还想查看没有依赖关系的组件,请仅显示 L

L[lengths(L) > 0]

给予:

$`F=m*a`
[1] "m=2" "a=4"

$`P=F/S`
[1] "F=m*a" "S=10" 
 
$`V=m/rho`
[1] "m=2"   "rho=1"

$`T=(P*V)/(n*R)`
[1] "P=F/S"   "V=m/rho" "n=0.412" "R=8.314"

并反转列表:

lapply(split(stack(L), stack(L)$values), function(x) as.character(x$ind))

给予:

$`a=4`
[1] "F=m*a"

$`F=m*a`
[1] "P=F/S"

$`m=2`
[1] "F=m*a"   "V=m/rho"

$`n=0.412`
[1] "T=(P*V)/(n*R)"

$`P=F/S`
[1] "T=(P*V)/(n*R)"

$`R=8.314`
[1] "T=(P*V)/(n*R)"

$`rho=1`
[1] "V=m/rho"

$`S=10`
[1] "P=F/S"

$`V=m/rho`
[1] "T=(P*V)/(n*R)"

注意

Lines <- "
  R=8.314;
  n=0.412;
  a=4;
  m=2;
  S=10;
  rho=1;
  F=m*a;
  P=F/S;
  V=m/rho;
  T=(P*V)/(n*R);
"

【讨论】:

  • 感谢您的回复,超级有帮助!。我试过了,但问题是我有很多方程和常数,有些方程很大,所以看起来不太好。所以,我有两个想法来改进它:1)在我附上的图中,有一种公式的层次结构而不是随机性(如你的图)。有没有办法做到这一点? 2)有没有办法不写方程式而只写字母?例如,类似 a-> F
  • 如果定义 L 的两个语句被替换为 L &lt;- setNames(lapply(rhs, function(x) all.vars(parse(text = x))), lhs) 则只有左侧会出现在图表中。
  • 谢谢!和层次风格?比如,顶部的常数和最后一个方程 T=(PV)/(nR) 和底部?
  • igraph 有关于如何手动指定节点位置的文档。
猜你喜欢
  • 1970-01-01
  • 2018-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-13
相关资源
最近更新 更多