matplotlib 使用Python或graphviz的鱼骨图

r1wp621o  于 2022-12-13  发布在  Python
关注(0)|答案(2)|浏览(248)

我正在尝试用Python生成鱼骨图(因果图或石川图)。有没有办法让它更像标准的鱼骨图?

from graphviz import Digraph

A=[('HW', 'Root'), ('SW', 'Root'),
  ('Electric', 'HW'), ('ink', 'HW'), ('windows', 'SW'), ('Drivers', 'SW'),
  ('Yellow', 'ink'), ('blue', 'ink'), ('pink', 'ink'),
  ('FE', 'Drivers'), ('BE', 'Drivers')]
e = Digraph()
e.attr(rankdir='LR')
for a in A:
    e.node(a[0])
    e.edge(a[0], a[1])
e.view()

qoefvg9y

qoefvg9y1#

用graphviz做这样的事情真的很难,因为graphviz在如何安排事情上真的有自己的想法。你考虑过用matplotlib解决这个问题吗?matplotlib中有一个example creating a timeline,你可以用它作为基础,并根据需要进行修改。

gupuwyp2

gupuwyp22#

如上所述,鱼骨图超出了Graphviz的规范。下面是一个“相当不错”(旁观者的眼睛)的示例图版本。如果你觉得它可用,我会附上输入文件并解释发生了什么。如果不可用,请解释你需要什么。
问题:

  • 线交叉点不整齐
  • 结果需要三个步骤
  • 一个月一个月的运行
  • 使用GVPR(Graphviz程序)进行后处理,以创建叉骨“耙”
  • neato -n运行以创建可视文件
  • 这不处理第二/第三关系(bonees-off-of-bones)输入文件:
// non-directed graph, though directed would also work
graph W {
  // no splines
  graph [splines=line]
  // use underline-shape
  node [shape=underline]
  // first, we define the nodes & edges that make the centerline edge
  // note using standard ranking (top-to-bottom)
  // centerline is set on one rank
  // added a centerline attribute to make adding rak easier
  // dot ignores unknown attributes
  // gvpr program will use 
  {
    rank=same
    node [shape=rect style=invis centerline=true]  // mark centerline
    edge [headclip=false tailclip=false]
    p1 [group=g1]
    p2 [group=g2]
    p3 [group=g3]
    pstart:c -- p1:c --  p2:c --  p3:c
    pend [label=" Defect XXX" shape=plain style=solid]
    p3:c -- pend:w [dir=forward arrowhead=normal]
  }
  // define labels on top (min) rank
  // plain, not underlined
  {
    rank=min
    node [shape=plain]    
    measurements  materials personnel
  }
  // define leftmost "fishbone"
  // group attribte helps keep nodes aligned vertically
  {
  node [group=g1]
  measurements:se -- calibration:e -- microscopes:e -- inspectors:e
  // send this edge to the middle of the centerlin point
  inspectors:e -- p1:c  [headclip=false]
  }
  // define next "fishbone" to right
  {
  node [group=g2]
  materials:s--alloys:e--Lubricants:e--Suppliers:e 
  Suppliers:e -- p2:c [headclip=false]
  }
  // define rightmost "fishbone"
  {
  node [group=g3]
  personnel:s--shifts:e--training:e--operators:e--"another thing":e -- p3:c [headclip=false]
  }
  ////////////////////////////////////////////////////////////////
  // from here on, we are drawing edges out from centerline
  ////////////////////////////////////////////////////////////////
  // define labels on bottom (max) rank
  {
    rank=max
    node [shape=plaintext]
    Environment Methods Machines
  }
  {
  node [group=g1]
  p1 -- Humidity:e [tailclip=false]
  Humidity:e -- temperature:e -- Environment:n
  }
  {
  node [group=g2]
  p2 -- Angle:e  [tailclip=false]
  Angle:e --Engager:e-- Brake:e-- Methods:n 
  }
  {
  node [group=g3]
  p3 -- "blade wear":e  [tailclip=false]
  "blade wear":e -- speed:e -- Machines:n
  }
}

运行上面的点,你会得到这个-不是很远,但不是一个鱼骨图:

现在,wishbone.gvpr-gvprhttps://www.graphviz.org/pdf/gvpr.1.pdf)程序将添加鱼骨耙:

BEGIN{
  int nIndx=0;
  float centerY=-999.9, dY, angleAdj, minY=9999, maxY=-9999;
  node_t Node[];
  graph_t theRoot, subG;
  void doErrs(string eString){
     printf(2, "Error:: %s\n", eString);
     print("// Error:: %s\n", eString); // temporary, for debugging
  }
}
///////////////////////////////////////////////////////////////////////////
N{
   Node[++nIndx]=$;
   if ((hasAttr($, "centerline")) && ($.centerline!="")){
      centerY=$.Y;
   }
   if ($.Y >maxY)
     maxY=$.Y;
   if ($.Y < minY)
     minY=$.Y;
}
////////////////////////////////////////////////////////////////////////////
END_G{
  if (centerY==-999.9){
      estr="\"centerline\" attribute is missing"; doErrs(estr);;
      exit(9);
  }
  $G.bb="";
  for (Node[nIndx]){
    print("//  pos before: ",Node[nIndx].pos);
    dY=Node[nIndx].Y-centerY;
    print("//  dY (1) : ", dY);
    // get absolute value
    if (dY<0){
      dY=-dY;
    }
    print("//  dY (2) : ", dY);
    Node[nIndx].pos=(string)(Node[nIndx].X - .25*dY) + "," + (string)Node[nIndx].Y;
    print("//  pos after: ", Node[nIndx].pos);
  }
}

gvpr程序调整X坐标

然后neato -n(https://graphviz.org/faq/#FaqDotWithNodeCoords)修复这些边。
最后是命令行(Linux),它可以完成所有操作-(如果Windows不支持管道,只需将中间输出发送到临时文件)

dot -Tdot myfile.gv |
gvpr -c -f wishbone.gvpr  |
neato -n -Tpng >myfile.png

赠送:

呼!

相关问题