Answers.Body: <p>OMG guys! I did it. With my limited skills it took me two days to come up with a script that turn PGN of an opening to a nice graph. All you need to do is insert the PGN and run Graphviz with &quot;dot -Tsvg graph.dot &gt; output.svg&quot; after running the python script.</p>
  <pre><code>import ast
  
  pgn = &quot;1.e4 c5 2.Nf3 ( 2.c3 Nf6 ( 2...f6 3.Na3 ) 3.e5 Nd5 ) Nc6 3.d4 cxd4 4.Nxd4 ( 4.c3 ) g6&quot;
  
  hauptzaehler = 0
  knoten = []
  
  class Node:
    def __init__(self, name, move, parent):
      self.name = name
      self.move = move
      self.is_white = None
      self.parent = parent
  
  def pgn_to_list(pgn):
    pgn = pgn[pgn.find(&quot;1.&quot;):]
    pgn = pgn.split(&quot;*&quot;, 1)[0]
    for i in range(11,26):
      pgn = pgn.replace(str(i) + &quot;.&quot;, &quot;&quot;)
    for i in range(1,11):
      pgn = pgn.replace(str(i) + &quot;.&quot;, &quot;&quot;)
    pgn = pgn.replace(&quot;.&quot;, &quot;&quot;)
    pgn = pgn.rstrip()
    pgn = pgn.replace(&quot; &quot;, &quot;\&quot;, \&quot;&quot;)
    pgn = pgn.replace(&quot;\&quot;(\&quot;, &quot;, &quot;[&quot;)
    pgn = pgn.replace(&quot;, \&quot;)\&quot;&quot;, &quot;]&quot;)
    pgn = &quot;[\&quot;&quot; + pgn + &quot;\&quot;]&quot;
    pgn = pgn.replace(&quot;, \&quot;)\&quot;&quot;, &quot;]&quot;)
    feld = ast.literal_eval(pgn)
    return feld
  
  pgn = pgn_to_list(pgn)
  
  def mache_dicts(feld):
    global hauptzaehler
    for i in feld:
      if type(i) != list:
        feld[feld.index(i)] = {&quot;index&quot;: hauptzaehler, &quot;zug&quot;: i, &quot;parent&quot;: None}
        hauptzaehler += 1
      else:
        mache_dicts(i)
    return feld
  
  def parentify1(feld):
    for i in range(len(feld)-1,-1,-1):
      if type(feld[i]) != list:
        if (i == 0):
          feld[0][&quot;parent&quot;] = None
        else:
          for x in range(i-1,-1,-1):
            if type(feld[x]) != list:
              eltern = feld[x][&quot;index&quot;]
              feld[i][&quot;parent&quot;] = eltern
              break
      else:
        parentify1(feld[i])
    return None
  
  def parentify2(feld):
    eltern0 = None
    eltern1 = None
    for i in range(0,len(feld)):
      if type(feld[i]) != list:
        eltern0 = eltern1
        eltern1 = feld[i][&quot;index&quot;]
      else:
        feld[i][0][&quot;parent&quot;] = eltern0
        parentify2(feld[i])
    return None
  
  def knotenliste(pgn):
    global knoten
    for i in pgn:
      if type(i) != list:
        knoten.append(Node(i[&quot;index&quot;],i[&quot;zug&quot;],i[&quot;parent&quot;]))
      else:
        knotenliste(i)
    return None
  
  def get_parent(feld, parent):
    for i in feld:
      if (i.name == parent):
        return i
  
  def einfaerben(knoten):
    for i in knoten:
      if (i.parent == None):
        i.is_white = True
      elif (get_parent(knoten, i.parent).is_white == True):
        i.is_white = False
      elif (get_parent(knoten, i.parent).is_white == False):
        i.is_white = True
    return None
  
  def get_kinder(feld, index):
    kinder = []
    for i in feld:
      if (i.parent == index):
        kinder.append(i.name)
    kinderstring = &quot;&quot;
    for x in kinder:
      kinderstring = kinderstring + &quot; n&quot; + str(index) + &quot; -&gt; n&quot; + str(x) + &quot;;&quot;
    return kinderstring
  
  def write_dot(knotenfeld):
    open(&quot;graph.dot&quot;, &quot;w&quot;).close()
    dot = open(&quot;graph.dot&quot;, &quot;a&quot;)
    dot.write(&quot;digraph chess_openings {\n  {\n    node [shape=box];\n&quot;)
    for i in knotenfeld:
      schwarz = &quot;&quot;
      if (i.is_white == False):
        schwarz = &quot;, style=filled&quot;
      dot.write(&quot;    n&quot; + str(i.name) + &quot;[label=\&quot;&quot; + i.move + &quot;\&quot;&quot; + schwarz + &quot;];&quot; + get_kinder(knotenfeld, i.name) + &quot;\n&quot;)
    dot.write(&quot;  }\n}&quot;)
    dot.close()
    return None
  
  pgn = mache_dicts(pgn)
  parentify1(pgn)
  parentify2(pgn)
  knotenliste(pgn)
  for i in range(0,len(knoten)):
    einfaerben(knoten)
  write_dot(knoten)
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-18T07:55:27.790Z
Answers.LastActivityDate: 2023-02-18T08:17:00.093Z
Answers.LastEditDate: 2023-02-18T08:17:00.093Z
Answers.UserDisplayName: Tiru84
Answers.Body: <p>The free program DiagTransfer version 3.0.1 will make a position diagram from a pgn or epd file. Works well on Windows 10. I've used it hundreds of times to insert chess positions into word processor files or print diagrams on file cards. Has several options including adding arrows.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-12T20:11:04.443Z
Answers.Text: I'm looking to turn a png into a tree-like graph. Probably it doesn't do this?
Answers.UserDisplayName: Tiru84
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-12T20:02:56.670Z
Answers.LastActivityDate: 2023-02-12T20:02:56.670Z
Answers.UserDisplayName: dlemper
Answers.Body: <p>The website <a href="https://www.chesstree.net/" rel="nofollow noreferrer">Chess Tree</a> allows to import pgn and show them as an horizontal tree, with the moves inside circles. I have not seen an option to graphically export the tree or print it. Perhaps the author trust the print option in web explorer menu for this purpose. It allows also to activate an overlay with move statistics of the in site tree data base.</p>
  <p>Another one that could catch your interest, comparing your repertoire with your games, is <a href="https://chesslens.app./" rel="nofollow noreferrer">Chess Lens</a>. A description of the app by its programer is in this <a href="https://www.chess.com/blog/yarrichar/chess-repertoire-tool" rel="nofollow noreferrer">article</a>.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-15T16:34:26.467Z
Answers.Text: It would be trivial to take a screenshot of it
Answers.UserDisplayName: Darren H
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-15T07:34:56.490Z
Answers.LastActivityDate: 2023-02-15T07:51:07.390Z
Answers.LastEditDate: 2023-02-15T07:51:07.390Z
Answers.UserDisplayName: djnavas
Body: <p>Does anyone here knows how to turn a PGN, let's say for example</p>
  <blockquote>
  <p>1.e4 c5 2.Nf3 ( 2.c3 Nf6 ( 2...f6 3.Na3 ) 3.e5 Nd5 ) Nc6 3.d4 cxd4 4.Nxd4 ( 4.c3 ) g6</p>
  </blockquote>
  <p>into an image? I preferably would like to put out a *.dot-file (Graphviz) that manually created looks like this in the example</p>
  <pre><code>digraph chess_openings {
      {
          node [shape=box];
          n1 [label=&quot;e4&quot;]; n1-&gt; n2;
          n2 [label=&quot;c5&quot;, style=filled]; n2 -&gt; n3; n2 -&gt; n4;
          n3 [label=&quot;Nf3&quot;]; n3 -&gt; n8;
          n4 [label=&quot;c3&quot;]; n4 -&gt; n5;
          n5 [label=&quot;Nf6&quot;, style=filled]; n5 -&gt; n6;
          n6 [label=&quot;e5&quot;]; n6 -&gt; n7;
          n7 [label=&quot;d5&quot;, style=filled];
          n8 [label=&quot;Nc6&quot;, style=filled]; n8 -&gt; n9;
          n9 [label=&quot;d4&quot;]; n9 -&gt; n10;
          n10 [label=&quot;cxd4&quot;, style=filled]; n10 -&gt; n11;
          n11 [label=&quot;Nxd4&quot;]; n11 -&gt; n12;
          n12 [label=&quot;g6&quot;, style=filled];
      }
  }
  </code></pre>
  <p>which Graphviz turns into that kind of image</p>
  <p><a href="https://i.sstatic.net/1bYDn.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/1bYDn.png" alt="enter image description here" /></a></p>
  <p>So I'm looking for either a simple and free software that can create such graphs automatically or a script that converts a pgn-file into a dot-file. Can anyone help?</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-02-15T08:23:48.700Z
Comments.Text: Since .dot Graphviz is plaintext, I suggest you write a little Python script yourself. (Depending on the number of bracket depth it shall be able to cope with, this is a hour's work at most for a halfways experienced programmer.)
Comments.UserDisplayName: Hauke Reddmann
Tags: <opening><software><programming><pgn>
Title: How to turn the PGN of opening into a image?
ThreadText: # How to turn the PGN of opening into a image?
  
  (Asked by: username_0 on 2023-02-12)
  
  Does anyone here knows how to turn a PGN, let's say for example
  
  1.e4 c5 2.Nf3 ( 2.c3 Nf6 ( 2...f6 3.Na3 ) 3.e5 Nd5 ) Nc6 3.d4 cxd4 4.Nxd4 ( 4.c3 ) g6
  
  into an image? I preferably would like to put out a *.dot-file (Graphviz) that manually created looks like this in the example
  digraph chess_openings {
      {
          node [shape=box];
          n1 [label="e4"]; n1-> n2;
          n2 [label="c5", style=filled]; n2 -> n3; n2 -> n4;
          n3 [label="Nf3"]; n3 -> n8;
          n4 [label="c3"]; n4 -> n5;
          n5 [label="Nf6", style=filled]; n5 -> n6;
          n6 [label="e5"]; n6 -> n7;
          n7 [label="d5", style=filled];
          n8 [label="Nc6", style=filled]; n8 -> n9;
          n9 [label="d4"]; n9 -> n10;
          n10 [label="cxd4", style=filled]; n10 -> n11;
          n11 [label="Nxd4"]; n11 -> n12;
          n12 [label="g6", style=filled];
      }
  }
  
  which Graphviz turns into that kind of image
  
  So I'm looking for either a simple and free software that can create such graphs automatically or a script that converts a pgn-file into a dot-file. Can anyone help?
  
  **Tags:** opening, software, programming, pgn
  
  > **Comments:**
  > **username_1**: Since .dot Graphviz is plaintext, I suggest you write a little Python script yourself. (Depending on the number of bracket depth it shall be able to cope with, this is a hour's work at most for a halfways experienced programmer.)  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_0 on 2023-02-18. Score: 1 | Accepted answer
  
  OMG guys! I did it. With my limited skills it took me two days to come up with a script that turn PGN of an opening to a nice graph. All you need to do is insert the PGN and run Graphviz with "dot -Tsvg graph.dot > output.svg" after running the python script.
  import ast
  
  pgn = "1.e4 c5 2.Nf3 ( 2.c3 Nf6 ( 2...f6 3.Na3 ) 3.e5 Nd5 ) Nc6 3.d4 cxd4 4.Nxd4 ( 4.c3 ) g6"
  
  hauptzaehler = 0
  knoten = []
  
  class Node:
    def __init__(self, name, move, parent):
      self.name = name
      self.move = move
      self.is_white = None
      self.parent = parent
  
  def pgn_to_list(pgn):
    pgn = pgn[pgn.find("1."):]
    pgn = pgn.split("*", 1)[0]
    for i in range(11,26):
      pgn = pgn.replace(str(i) + ".", "")
    for i in range(1,11):
      pgn = pgn.replace(str(i) + ".", "")
    pgn = pgn.replace(".", "")
    pgn = pgn.rstrip()
    pgn = pgn.replace(" ", "\", \"")
    pgn = pgn.replace("\"(\", ", "[")
    pgn = pgn.replace(", \")\"", "]")
    pgn = "[\"" + pgn + "\"]"
    pgn = pgn.replace(", \")\"", "]")
    feld = ast.literal_eval(pgn)
    return feld
  
  pgn = pgn_to_list(pgn)
  
  def mache_dicts(feld):
    global hauptzaehler
    for i in feld:
      if type(i) != list:
        feld[feld.index(i)] = {"index": hauptzaehler, "zug": i, "parent": None}
        hauptzaehler += 1
      else:
        mache_dicts(i)
    return feld
  
  def parentify1(feld):
    for i in range(len(feld)-1,-1,-1):
      if type(feld[i]) != list:
        if (i == 0):
          feld[0]["parent"] = None
        else:
          for x in range(i-1,-1,-1):
            if type(feld[x]) != list:
              eltern = feld[x]["index"]
              feld[i]["parent"] = eltern
              break
      else:
        parentify1(feld[i])
    return None
  
  def parentify2(feld):
    eltern0 = None
    eltern1 = None
    for i in range(0,len(feld)):
      if type(feld[i]) != list:
        eltern0 = eltern1
        eltern1 = feld[i]["index"]
      else:
        feld[i][0]["parent"] = eltern0
        parentify2(feld[i])
    return None
  
  def knotenliste(pgn):
    global knoten
    for i in pgn:
      if type(i) != list:
        knoten.append(Node(i["index"],i["zug"],i["parent"]))
      else:
        knotenliste(i)
    return None
  
  def get_parent(feld, parent):
    for i in feld:
      if (i.name == parent):
        return i
  
  def einfaerben(knoten):
    for i in knoten:
      if (i.parent == None):
        i.is_white = True
      elif (get_parent(knoten, i.parent).is_white == True):
        i.is_white = False
      elif (get_parent(knoten, i.parent).is_white == False):
        i.is_white = True
    return None
  
  def get_kinder(feld, index):
    kinder = []
    for i in feld:
      if (i.parent == index):
        kinder.append(i.name)
    kinderstring = ""
    for x in kinder:
      kinderstring = kinderstring + " n" + str(index) + " -> n" + str(x) + ";"
    return kinderstring
  
  def write_dot(knotenfeld):
    open("graph.dot", "w").close()
    dot = open("graph.dot", "a")
    dot.write("digraph chess_openings {\n  {\n    node [shape=box];\n")
    for i in knotenfeld:
      schwarz = ""
      if (i.is_white == False):
        schwarz = ", style=filled"
      dot.write("    n" + str(i.name) + "[label=\"" + i.move + "\"" + schwarz + "];" + get_kinder(knotenfeld, i.name) + "\n")
    dot.write("  }\n}")
    dot.close()
    return None
  
  pgn = mache_dicts(pgn)
  parentify1(pgn)
  parentify2(pgn)
  knotenliste(pgn)
  for i in range(0,len(knoten)):
    einfaerben(knoten)
  write_dot(knoten)
  
  
  ---
  
  ### Answer by username_2 on 2023-02-12. Score: 1
  
  The free program DiagTransfer version 3.0.1 will make a position diagram from a pgn or epd file. Works well on Windows 10. I've used it hundreds of times to insert chess positions into word processor files or print diagrams on file cards. Has several options including adding arrows.
  
  > **Comments:**
  > **username_0**: I'm looking to turn a png into a tree-like graph. Probably it doesn't do this?  
  
  ---
  
  ### Answer by username_3 on 2023-02-15. Score: 0
  
  The website [Chess Tree](https://www.chesstree.net/) allows to import pgn and show them as an horizontal tree, with the moves inside circles. I have not seen an option to graphically export the tree or print it. Perhaps the author trust the print option in web explorer menu for this purpose. It allows also to activate an overlay with move statistics of the in site tree data base.
  
  Another one that could catch your interest, comparing your repertoire with your games, is [Chess Lens](https://chesslens.app./). A description of the app by its programer is in this [article](https://www.chess.com/blog/yarrichar/chess-repertoire-tool).
  
  > **Comments:**
  > **username_4**: It would be trivial to take a screenshot of it  
  
  ---
  
  