19 '''Visualize dot graphs via the xdot format.'''
21 __author__ =
"Jose Fonseca et al"
36 gi.require_version(
'Gtk',
'3.0')
37 gi.require_version(
'PangoCairo',
'1.0')
39 from gi.repository
import GLib
40 from gi.repository
import GObject
41 from gi.repository
import Gtk
42 from gi.repository
import Gdk
43 from gi.repository
import GdkPixbuf
44 from gi.repository
import Pango
45 from gi.repository
import PangoCairo
57 """Store pen attributes."""
61 self.
color = (0.0, 0.0, 0.0, 1.0)
77 """Create a copy of this pen."""
79 pen.__dict__ = self.__dict__.
copy()
84 pen.color = (1, 0, 0, 1)
85 pen.fillcolor = (1, .8, .8, 1)
90 """Abstract base class for all the drawing shapes."""
95 def draw(self, cr, highlight=False):
96 """Draw this shape with the given cairo context"""
97 raise NotImplementedError
101 if not hasattr(self,
'highlight_pen'):
113 LEFT, CENTER, RIGHT = -1, 0, 1
124 def draw(self, cr, highlight=False):
128 except AttributeError:
129 layout = PangoCairo.create_layout(cr)
133 context = layout.get_context()
134 fo = cairo.FontOptions()
135 fo.set_antialias(cairo.ANTIALIAS_DEFAULT)
136 fo.set_hint_style(cairo.HINT_STYLE_NONE)
137 fo.set_hint_metrics(cairo.HINT_METRICS_OFF)
139 PangoCairo.context_set_font_options(context, fo)
150 font = Pango.FontDescription()
153 markup = GObject.markup_escape_text(self.
t)
155 markup =
'<b>' + markup +
'</b>'
157 markup =
'<i>' + markup +
'</i>'
158 if self.
pen.underline:
159 markup =
'<span underline="single">' + markup +
'</span>'
160 if self.
pen.strikethrough:
161 markup =
'<s>' + markup +
'</s>'
162 if self.
pen.superscript:
163 markup =
'<sup><small>' + markup +
'</small></sup>'
164 if self.
pen.subscript:
165 markup =
'<sub><small>' + markup +
'</small></sub>'
167 success, attrs, text, accel_char = Pango.parse_markup(markup, -1,
'\x00')
169 layout.set_attributes(attrs)
171 font.set_family(self.
pen.fontname)
172 font.set_absolute_size(self.
pen.fontsize*Pango.SCALE)
173 layout.set_font_description(font)
176 layout.set_text(text, -1)
181 PangoCairo.update_layout(cr, layout)
185 width, height = layout.get_size()
186 width = float(width)/Pango.SCALE
187 height = float(height)/Pango.SCALE
200 if self.
j == self.
LEFT:
203 x = self.
x - 0.5*width
204 elif self.
j == self.
RIGHT:
209 y = self.
y - height + descent
215 cr.set_source_rgba(*self.
select_pen(highlight).color)
216 PangoCairo.show_layout(cr, layout)
221 cr.set_source_rgba(1, 0, 0, .9)
222 if self.
j == self.
LEFT:
225 x = self.
x - 0.5*self.
w
226 elif self.
j == self.
RIGHT:
228 cr.move_to(x, self.
y)
229 cr.line_to(x+self.
w, self.
y)
233 return regexp.search(self.
t)
is not None
247 def draw(self, cr, highlight=False):
248 pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.
path)
249 sx = float(self.
w)/float(pixbuf.get_width())
250 sy = float(self.
h)/float(pixbuf.get_height())
252 cr.translate(self.
x0, self.
y0 - self.
h)
254 Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0)
261 def __init__(self, pen, x0, y0, w, h, filled=False):
270 def draw(self, cr, highlight=False):
272 cr.translate(self.
x0, self.
y0)
273 cr.scale(self.
w, self.
h)
275 cr.arc(0.0, 0.0, 1.0, 0, 2.0*math.pi)
279 cr.set_source_rgba(*pen.fillcolor)
282 cr.set_dash(pen.dash)
283 cr.set_line_width(pen.linewidth)
284 cr.set_source_rgba(*pen.color)
296 def draw(self, cr, highlight=False):
304 cr.set_source_rgba(*pen.fillcolor)
308 cr.set_dash(pen.dash)
309 cr.set_line_width(pen.linewidth)
310 cr.set_source_rgba(*pen.color)
321 def draw(self, cr, highlight=False):
324 for x1, y1
in self.
points[1:]:
327 cr.set_dash(pen.dash)
328 cr.set_line_width(pen.linewidth)
329 cr.set_source_rgba(*pen.color)
341 def draw(self, cr, highlight=False):
344 for i
in range(1, len(self.
points), 3):
346 x2, y2 = self.
points[i + 1]
347 x3, y3 = self.
points[i + 2]
348 cr.curve_to(x1, y1, x2, y2, x3, y3)
351 cr.set_source_rgba(*pen.fillcolor)
355 cr.set_dash(pen.dash)
356 cr.set_line_width(pen.linewidth)
357 cr.set_source_rgba(*pen.color)
367 def draw(self, cr, highlight=False):
369 shape.draw(cr, highlight=highlight)
373 if shape.search_text(regexp):
383 if highlight
is None:
384 highlight = set([item])
390 def __init__(self, item, x, y, highlight=None, url=None):
394 if highlight
is None:
395 highlight = set([item])
401 """Base class for graph nodes and edges."""
404 CompoundShape.__init__(self, shapes)
419 Element.__init__(self, shapes)
433 return self.
x1 <= x
and x <= self.
x2 and self.
y1 <= y
and y <= self.
y2
439 return Url(self, self.
url)
444 return Jump(self, self.
x, self.
y)
448 return "<Node %s>" % self.
id
454 return deltax*deltax + deltay*deltay
460 Element.__init__(self, shapes)
483 return Jump(self, self.
dst.x, self.
dst.y, highlight=set([self, self.
dst]),url=self.
url)
485 return Jump(self, self.
src.x, self.
src.y, highlight=set([self, self.
src]),url=self.
url)
489 return "<Edge %s -> %s>" % (self.
src, self.
dst)
494 def __init__(self, width=1, height=1, shapes=(), nodes=(), edges=(), subgraph_shapes={}):
507 def draw(self, cr, highlight_items=None):
508 if highlight_items
is None:
510 cr.set_source_rgba(0.0, 0.0, 0.0, 1.0)
512 cr.set_line_cap(cairo.LINE_CAP_BUTT)
513 cr.set_line_join(cairo.LINE_JOIN_MITER)
517 for edge
in self.
edges:
518 edge.draw(cr, highlight=(edge
in highlight_items))
519 for node
in self.
nodes:
520 node.draw(cr, highlight=(node
in highlight_items))
523 for node
in self.
nodes:
524 if node.is_inside(x, y):
526 for edge
in self.
edges:
527 if edge.is_inside(x, y):
531 for node
in self.
nodes:
532 url = node.get_url(x, y)
538 for edge
in self.
edges:
539 jump = edge.get_jump(x, y)
542 for node
in self.
nodes:
543 jump = node.get_jump(x, y)
559 """Parser for xdot drawing attributes.
561 - http://www.graphviz.org/doc/info/output.html#d:xdot
573 return self.
pos < len(self.
buf)
576 buf = buf.replace(
'\\"',
'"')
577 buf = buf.replace(
'\\n',
'\n')
581 pos = self.
buf.find(b
" ", self.
pos)
582 res = self.
buf[self.
pos:pos]
585 res = res.decode(
'utf-8')
589 while self.
pos < len(self.
buf)
and self.
buf[self.
pos : self.
pos + 1].isspace():
605 pos = self.
buf.find(b
"-", self.
pos) + 1
607 res = self.
buf[pos:self.
pos]
609 res = res.decode(
'utf-8')
625 hex2float =
lambda h: float(int(h, 16)/255.0)
626 r = hex2float(c[1:3])
627 g = hex2float(c[3:5])
628 b = hex2float(c[5:7])
630 a = hex2float(c[7:9])
631 except (IndexError, ValueError):
634 elif c1.isdigit()
or c1 ==
".":
636 h, s, v = map(float, c.replace(
",",
" ").split())
637 r, g, b = colorsys.hsv_to_rgb(h, s, v)
640 elif c1 ==
"[" or c1 ==
"(":
641 sys.stderr.write(
'warning: color gradients not supported yet\n')
648 color = Gdk.color_parse(c)
660 dummy, scheme, index = c.split(
'/')
661 r, g, b = brewer_colors[scheme][int(index)]
662 except (ValueError, KeyError):
672 sys.stderr.write(
"warning: unknown color '%s'\n" % c)
681 color = s.read_color()
682 if color
is not None:
685 color = s.read_color()
686 if color
is not None:
690 style = s.read_text()
691 if style.startswith(
"setlinewidth("):
692 lw = style.split(
"(")[1].split(
")")[0]
695 elif style
in (
"solid",
"dashed",
"dotted"):
698 size = s.read_float()
702 x, y = s.read_point()
711 x0, y0 = s.read_point()
716 x0, y0 = s.read_point()
736 x0, y0 = s.read_point()
742 sys.stderr.write(
"error: unknown xdot opcode '%s'\n" % op)
752 self.
pen.fillcolor = color
754 self.
pen.color = color
757 self.
pen.linewidth = linewidth
762 elif style ==
"dashed":
763 self.
pen.dash = (6, )
764 elif style ==
"dotted":
765 self.
pen.dash = (2, 4)
768 self.
pen.fontsize = size
769 self.
pen.fontname = name
772 self.
pen.bold = bool(flags & BOLD)
773 self.
pen.italic = bool(flags & ITALIC)
774 self.
pen.underline = bool(flags & UNDERLINE)
775 self.
pen.superscript = bool(flags & SUPERSCRIPT)
776 self.
pen.subscript = bool(flags & SUBSCRIPT)
777 self.
pen.strikethrough = bool(flags & STRIKE_THROUGH)
778 self.
pen.overline = bool(flags & OVERLINE)
779 if self.
pen.overline:
780 sys.stderr.write(
'warning: overlined text not supported yet\n')
816 def __init__(self, msg=None, filename=None, line=None, col=None):
823 return ':'.join([str(part)
for part
in (self.
filename, self.
line, self.
col, self.
msg)
if part !=
None])
827 """Stateless scanner."""
838 flags |= re.IGNORECASE
840 b
'|'.join([b
'(' + regexp + b
')' for type, regexp, test_lit
in self.
tokens]),
850 type, regexp, test_lit = self.
tokens[mo.lastindex - 1]
853 type = self.
literals.get(text, type)
854 return type, text, pos
856 c = buf[pos : pos + 1]
857 return self.
symbols.get(c,
None), c, pos + 1
875 newline_re = re.compile(br
'\r\n?|\n')
877 def __init__(self, buf = None, pos = 0, filename = None, fp = None):
881 length = os.path.getsize(fp.name)
891 buf = mmap.mmap(fileno, length, access = mmap.ACCESS_READ)
892 pos = os.lseek(fileno, 0, 1)
900 except AttributeError:
917 assert isinstance(text, bytes)
918 assert pos + len(text) == endpos
920 type, text = self.filter(type, text)
926 msg =
'unexpected char %r' % (text,)
930 return Token(type = type, text = text, line = line, col = col)
935 for mo
in self.
newline_re.finditer(text, pos):
942 tabpos = text.find(b
'\t', pos)
945 self.
col += tabpos - pos
948 self.
col += len(text) - pos
960 msg =
'unexpected token %r' % self.
lookahead.text,
961 filename = self.
lexer.filename,
969 msg =
'unexpected end of file',
970 filename = self.
lexer.filename,
1017 (ID, br
'[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*',
True),
1020 (ID, br
'-?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)',
False),
1023 (STR_ID, br
'"[^"\\]*(?:\\.[^"\\]*)*"',
False),
1026 (HTML_ID, br
'<[^<>]*(?:<[^<>]*>[^<>]*)*>',
False),
1029 (EDGE_OP, br
'-[>-]',
False),
1049 b
'digraph': DIGRAPH,
1052 b
'subgraph': SUBGRAPH,
1068 text = text.replace(b
'\\\r\n', b
'')
1069 text = text.replace(b
'\\\r', b
'')
1070 text = text.replace(b
'\\\n', b
'')
1073 text = text.replace(b
'\\"', b
'"')
1080 elif type == HTML_ID:
1090 Parser.__init__(self, lexer)
1110 shapes_before = set(self.shapes)
1121 new_shapes = set(self.shapes) - shapes_before
1122 self.subgraph_shapes[id] = [s
for s
in new_shapes
if not any([s
in ss
for ss
in list(self.subgraph_shapes.values())])]
1137 elif self.
lookahead.type
in (SUBGRAPH, LCURLY):
1147 for i
in range(0, len(node_ids) - 1):
1148 self.
handle_edge(node_ids[i], node_ids[i + 1], attrs)
1164 name = name.decode(
'utf-8')
1212 class XDotParser(DotParser):
1218 DotParser.__init__(self, lexer)
1233 xdotversion = attrs[
'xdotversion']
1238 sys.stderr.write(
'warning: xdot version %s, but supported is %s\n' % (xdotversion, self.
XDOTVERSION))
1247 xmin, ymin, xmax, ymax = map(float, bb.split(b
","))
1255 self.
width = max(xmax - xmin, 1)
1256 self.
height = max(ymax - ymin, 1)
1260 for attr
in (
"_draw_",
"_ldraw_",
"_hdraw_",
"_tdraw_",
"_hldraw_",
"_tldraw_"):
1263 self.
shapes.extend(parser.parse())
1272 w = float(attrs.get(
'width', 0))*72
1273 h = float(attrs.get(
'height', 0))*72
1275 for attr
in (
"_draw_",
"_ldraw_"):
1278 shapes.extend(parser.parse())
1279 url = attrs.get(
'URL',
None)
1280 node =
Node(id, x, y, w, h, shapes, url)
1283 self.
nodes.append(node)
1293 for attr
in (
"_draw_",
"_ldraw_",
"_hdraw_",
"_tdraw_",
"_hldraw_",
"_tldraw_"):
1296 shapes.extend(parser.parse())
1297 url = attrs.get(
'URL',
None)
1301 self.
edges.append(
Edge(src, dst, points, shapes, url))
1304 DotParser.parse(self)
1308 x, y = pos.split(b
",")
1309 return self.
transform(float(x), float(y))
1313 for entry
in pos.split(b
' '):
1314 fields = entry.split(b
',')
1321 points.append(self.
transform(float(x), float(y)))
1361 class LinearAnimation(Animation):
1367 Animation.start(self)
1371 self.
animate(max(0, min(t, 1)))
1378 class MoveToAnimation(LinearAnimation):
1381 Animation.__init__(self, dot_widget)
1398 MoveToAnimation.__init__(self, dot_widget, target_x, target_y)
1408 visible = min(rect.width, rect.height) / self.
dot_widget.zoom_ratio
1411 desired_middle_zoom = visible / distance
1412 self.
extra_zoom = min(0, 4 * (desired_middle_zoom - middle_zoom))
1416 self.
dot_widget.zoom_ratio = c*t + b*t*(1-t) + a*(1-t)
1417 self.
dot_widget.zoom_to_fit_on_resize =
False
1418 MoveToAnimation.animate(self, t)
1433 window, x, y, state = event.window.get_device_position(event.device)
1435 x, y, state = event.x, event.y, event.state
1438 self.
drag(deltax, deltay)
1463 class NullAction(DragAction):
1467 window, x, y, state = event.window.get_device_position(event.device)
1469 x, y, state = event.x, event.y, event.state
1471 item = dot_widget.get_url(x, y)
1473 item = dot_widget.get_jump(x, y)
1474 if item
is not None:
1475 dot_widget.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))
1476 dot_widget.set_highlight(item.highlight)
1478 dot_widget.get_window().set_cursor(
None)
1479 dot_widget.set_highlight(
None)
1485 self.
dot_widget.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.FLEUR))
1493 self.
dot_widget.get_window().set_cursor(
None)
1501 self.
dot_widget.zoom_ratio *= 1.005 ** (deltax + deltay)
1502 self.
dot_widget.zoom_to_fit_on_resize =
False
1516 cr.set_source_rgba(.5, .5, 1.0, 0.25)
1521 cr.set_source_rgba(.5, .5, 1.0, 1.0)
1522 cr.set_line_width(1)
1541 """GTK widget that draws dot graphs."""
1545 'clicked' : (GObject.SIGNAL_RUN_LAST,
None, (str, object))
1551 Gtk.DrawingArea.__init__(self)
1556 self.set_can_focus(
True)
1558 self.connect(
"draw", self.
on_draw)
1559 self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK)
1562 self.add_events(Gdk.EventMask.POINTER_MOTION_MASK |
1563 Gdk.EventMask.POINTER_MOTION_HINT_MASK |
1564 Gdk.EventMask.BUTTON_RELEASE_MASK |
1565 Gdk.EventMask.SCROLL_MASK)
1573 GLib.timeout_add(1000, self.
update)
1575 self.
x, self.
y = 0.0, 0.0
1590 p = subprocess.Popen(
1592 stdin=subprocess.PIPE,
1593 stdout=subprocess.PIPE,
1594 stderr=subprocess.PIPE,
1596 universal_newlines=
False
1598 except OSError
as exc:
1599 error =
'%s: %s' % (self.
filter, exc.strerror)
1600 p = subprocess.CalledProcessError(exc.errno, self.
filter, exc.strerror)
1602 xdotcode, error = p.communicate(dotcode)
1603 error = error.rstrip()
1605 error = error.decode()
1606 sys.stderr.write(error +
'\n')
1607 if p.returncode != 0:
1608 self.error_dialog(error)
1614 if isinstance(dotcode, str):
1615 dotcode = dotcode.encode(
'utf-8')
1617 if xdotcode
is None:
1621 except ParseError
as ex:
1622 self.error_dialog(str(ex))
1625 if filename
is None:
1633 assert isinstance(xdotcode, bytes)
1635 self.
graph = parser.parse()
1656 cr.set_source_rgba(1.0, 1.0, 1.0, 1.0)
1660 rect = self.get_allocation()
1661 cr.translate(0.5*rect.width, 0.5*rect.height)
1663 cr.translate(-self.
x, -self.
y)
1673 return self.
x, self.
y
1687 zoom_ratio = min(zoom_ratio, 1E4)
1688 zoom_ratio = max(zoom_ratio, 1E-6)
1691 self.
x = self.
graph.width/2
1692 self.
y = self.
graph.height/2
1693 elif pos
is not None:
1694 rect = self.get_allocation()
1697 y -= 0.5*rect.height
1705 rect = self.get_allocation()
1706 width = abs(x1 - x2)
1707 height = abs(y1 - y2)
1708 if width == 0
and height == 0:
1712 float(rect.width)/float(width),
1713 float(rect.height)/float(height)
1716 self.
x = (x1 + x2) / 2
1717 self.
y = (y1 + y2) / 2
1721 rect = self.get_allocation()
1727 float(rect.width)/float(self.
graph.width),
1728 float(rect.height)/float(self.
graph.height)
1733 ZOOM_INCREMENT = 1.25
1734 ZOOM_TO_FIT_MARGIN = 12
1751 if event.keyval == Gdk.KEY_Left:
1755 if event.keyval == Gdk.KEY_Right:
1759 if event.keyval == Gdk.KEY_Up:
1763 if event.keyval == Gdk.KEY_Down:
1767 if event.keyval
in (Gdk.KEY_Page_Up,
1774 if event.keyval
in (Gdk.KEY_Page_Down,
1776 Gdk.KEY_KP_Subtract):
1780 if event.keyval == Gdk.KEY_Escape:
1784 if event.keyval == Gdk.KEY_r:
1787 if event.keyval == Gdk.KEY_f:
1788 win = widget.get_toplevel()
1789 find_toolitem = win.uimanager.get_widget(
'/ToolBar/Find')
1790 textentry = find_toolitem.get_children()
1791 win.set_focus(textentry[0])
1793 if event.keyval == Gdk.KEY_q:
1796 if event.keyval == Gdk.KEY_p:
1801 print_settings =
None
1803 print_op = Gtk.PrintOperation()
1809 print_op.connect(
"draw_page", self.
draw_page)
1811 res = print_op.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.get_toplevel())
1812 if res == Gtk.PrintOperationResult.APPLY:
1816 operation.set_n_pages(1)
1820 cr = context.get_cairo_context()
1822 rect = self.get_allocation()
1823 cr.translate(0.5*rect.width, 0.5*rect.height)
1825 cr.translate(-self.
x, -self.
y)
1831 if event.button
in (1, 2):
1832 modifiers = Gtk.accelerator_get_default_mod_mask()
1833 if state & modifiers == Gdk.ModifierType.CONTROL_MASK:
1835 elif state & modifiers == Gdk.ModifierType.SHIFT_MASK:
1836 return ZoomAreaAction
1852 def is_click(self, event, click_fuzz=4, click_timeout=1.0):
1853 assert event.type == Gdk.EventType.BUTTON_RELEASE
1859 deltax = self.
pressx - event.x
1860 deltay = self.
pressy - event.y
1861 return (time.time() < self.
presstime + click_timeout
1862 and math.hypot(deltax, deltay) < click_fuzz)
1865 """Override this method in subclass to process
1866 click events. Note that element can be None
1867 (click on empty space)."""
1873 x, y = int(event.x), int(event.y)
1879 if event.button == 1:
1882 self.emit(
'clicked', url.url, event)
1885 if jump
is not None:
1890 if event.button == 1
or event.button == 2:
1895 if event.direction == Gdk.ScrollDirection.UP:
1897 pos=(event.x, event.y))
1899 if event.direction == Gdk.ScrollDirection.DOWN:
1901 pos=(event.x, event.y))
1918 rect = self.get_allocation()
1920 y -= 0.5*rect.height
1941 __gtype_name__ =
"FindMenuToolAction"
1944 return Gtk.ToolItem()
1951 <toolbar name="ToolBar">
1952 <toolitem action="Open"/>
1953 <toolitem action="Reload"/>
1954 <toolitem action="Print"/>
1956 <toolitem action="ZoomIn"/>
1957 <toolitem action="ZoomOut"/>
1958 <toolitem action="ZoomFit"/>
1959 <toolitem action="Zoom100"/>
1961 <toolitem name="Find" action="Find"/>
1966 base_title =
'Dot Viewer'
1969 Gtk.Window.__init__(self)
1976 window.set_default_size(512, 512)
1986 accelgroup = uimanager.get_accel_group()
1987 window.add_accel_group(accelgroup)
1990 actiongroup = Gtk.ActionGroup(
'Actions')
1994 actiongroup.add_actions((
1995 (
'Open', Gtk.STOCK_OPEN,
None,
None,
None, self.
on_open),
1996 (
'Reload', Gtk.STOCK_REFRESH,
None,
None,
None, self.
on_reload),
1997 (
'Print', Gtk.STOCK_PRINT,
None,
None,
"Prints the currently visible part of the graph", self.
dotwidget.on_print),
1998 (
'ZoomIn', Gtk.STOCK_ZOOM_IN,
None,
None,
None, self.
dotwidget.on_zoom_in),
1999 (
'ZoomOut', Gtk.STOCK_ZOOM_OUT,
None,
None,
None, self.
dotwidget.on_zoom_out),
2000 (
'ZoomFit', Gtk.STOCK_ZOOM_FIT,
None,
None,
None, self.
dotwidget.on_zoom_fit),
2001 (
'Zoom100', Gtk.STOCK_ZOOM_100,
None,
None,
None, self.
dotwidget.on_zoom_100),
2005 "Find a node by name",
None)
2006 actiongroup.add_action(find_action)
2009 uimanager.insert_action_group(actiongroup, 0)
2012 uimanager.add_ui_from_string(self.
ui)
2015 toolbar = uimanager.get_widget(
'/ToolBar')
2016 vbox.pack_start(toolbar,
False,
False, 0)
2018 vbox.pack_start(self.
dotwidget,
True,
True, 0)
2025 find_toolitem = uimanager.get_widget(
'/ToolBar/Find')
2027 self.
textentry.set_icon_from_stock(0, Gtk.STOCK_FIND)
2030 self.
textentry.set_activates_default(
True)
2039 regexp = re.compile(entry_text)
2040 for node
in dot_widget.graph.nodes:
2041 if node.search_text(regexp):
2042 found_items.append(node)
2046 entry_text = entry.get_text()
2049 dot_widget.set_highlight(
None)
2052 found_items = self.
find_text(entry_text)
2053 dot_widget.set_highlight(found_items)
2056 entry_text = entry.get_text()
2059 dot_widget.set_highlight(
None)
2062 found_items = self.
find_text(entry_text)
2063 dot_widget.set_highlight(found_items)
2064 if(len(found_items) == 1):
2065 dot_widget.animate_to(found_items[0].x, found_items[0].y)
2081 if filename
is None:
2084 self.set_title(os.path.basename(filename) +
' - ' + self.
base_title)
2088 fp = open(filename,
'rt')
2091 except IOError
as ex:
2095 chooser = Gtk.FileChooserDialog(title=
"Open dot File",
2096 action=Gtk.FileChooserAction.OPEN,
2097 buttons=(Gtk.STOCK_CANCEL,
2098 Gtk.ResponseType.CANCEL,
2100 Gtk.ResponseType.OK))
2101 chooser.set_default_response(Gtk.ResponseType.OK)
2103 filter = Gtk.FileFilter()
2104 filter.set_name(
"Graphviz dot files")
2105 filter.add_pattern(
"*.dot")
2106 chooser.add_filter(filter)
2107 filter = Gtk.FileFilter()
2108 filter.set_name(
"All files")
2109 filter.add_pattern(
"*")
2110 chooser.add_filter(filter)
2111 if chooser.run() == Gtk.ResponseType.OK:
2112 filename = chooser.get_filename()
2123 dlg = Gtk.MessageDialog(type=Gtk.MessageType.ERROR,
2124 message_format=message,
2125 buttons=Gtk.ButtonsType.OK)
2142 usage=
'\n\t%prog [file]',
2145 Up, Down, Left, Right scroll
2146 PageUp, +, = zoom in
2147 PageDown, - zoom out
2152 Escape halt animation
2153 Ctrl-drag zoom in/out
2154 Shift-drag zooms an area
2159 type=
'choice', choices=(
'dot',
'neato',
'twopi',
'circo',
'fdp'),
2160 dest=
'filter', default=
'dot',
2161 help=
'graphviz filter: dot, neato, twopi, circo, or fdp [default: %default]')
2163 '-n',
'--no-filter',
2164 action=
'store_const', const=
None, dest=
'filter',
2165 help=
'assume input is already filtered into xdot format (use e.g. dot -Txdot)')
2167 (options, args) = parser.parse_args(sys.argv[1:])
2169 parser.error(
'incorrect number of arguments')
2172 win.connect(
'delete-event', Gtk.main_quit)
2173 win.set_filter(options.filter)
2176 win.set_dotcode(sys.stdin.read())
2178 win.open_file(args[0])
2222 'accent3': [(127, 201, 127), (190, 174, 212), (253, 192, 134)],
2223 'accent4': [(127, 201, 127), (190, 174, 212), (253, 192, 134), (255, 255, 153)],
2224 'accent5': [(127, 201, 127), (190, 174, 212), (253, 192, 134), (255, 255, 153), (56, 108, 176)],
2225 'accent6': [(127, 201, 127), (190, 174, 212), (253, 192, 134), (255, 255, 153), (56, 108, 176), (240, 2, 127)],
2226 'accent7': [(127, 201, 127), (190, 174, 212), (253, 192, 134), (255, 255, 153), (56, 108, 176), (240, 2, 127), (191, 91, 23)],
2227 'accent8': [(127, 201, 127), (190, 174, 212), (253, 192, 134), (255, 255, 153), (56, 108, 176), (240, 2, 127), (191, 91, 23), (102, 102, 102)],
2228 'blues3': [(222, 235, 247), (158, 202, 225), (49, 130, 189)],
2229 'blues4': [(239, 243, 255), (189, 215, 231), (107, 174, 214), (33, 113, 181)],
2230 'blues5': [(239, 243, 255), (189, 215, 231), (107, 174, 214), (49, 130, 189), (8, 81, 156)],
2231 'blues6': [(239, 243, 255), (198, 219, 239), (158, 202, 225), (107, 174, 214), (49, 130, 189), (8, 81, 156)],
2232 'blues7': [(239, 243, 255), (198, 219, 239), (158, 202, 225), (107, 174, 214), (66, 146, 198), (33, 113, 181), (8, 69, 148)],
2233 'blues8': [(247, 251, 255), (222, 235, 247), (198, 219, 239), (158, 202, 225), (107, 174, 214), (66, 146, 198), (33, 113, 181), (8, 69, 148)],
2234 'blues9': [(247, 251, 255), (222, 235, 247), (198, 219, 239), (158, 202, 225), (107, 174, 214), (66, 146, 198), (33, 113, 181), (8, 81, 156), (8, 48, 107)],
2235 'brbg10': [(84, 48, 5), (0, 60, 48), (140, 81, 10), (191, 129, 45), (223, 194, 125), (246, 232, 195), (199, 234, 229), (128, 205, 193), (53, 151, 143), (1, 102, 94)],
2236 'brbg11': [(84, 48, 5), (1, 102, 94), (0, 60, 48), (140, 81, 10), (191, 129, 45), (223, 194, 125), (246, 232, 195), (245, 245, 245), (199, 234, 229), (128, 205, 193), (53, 151, 143)],
2237 'brbg3': [(216, 179, 101), (245, 245, 245), (90, 180, 172)],
2238 'brbg4': [(166, 97, 26), (223, 194, 125), (128, 205, 193), (1, 133, 113)],
2239 'brbg5': [(166, 97, 26), (223, 194, 125), (245, 245, 245), (128, 205, 193), (1, 133, 113)],
2240 'brbg6': [(140, 81, 10), (216, 179, 101), (246, 232, 195), (199, 234, 229), (90, 180, 172), (1, 102, 94)],
2241 'brbg7': [(140, 81, 10), (216, 179, 101), (246, 232, 195), (245, 245, 245), (199, 234, 229), (90, 180, 172), (1, 102, 94)],
2242 'brbg8': [(140, 81, 10), (191, 129, 45), (223, 194, 125), (246, 232, 195), (199, 234, 229), (128, 205, 193), (53, 151, 143), (1, 102, 94)],
2243 'brbg9': [(140, 81, 10), (191, 129, 45), (223, 194, 125), (246, 232, 195), (245, 245, 245), (199, 234, 229), (128, 205, 193), (53, 151, 143), (1, 102, 94)],
2244 'bugn3': [(229, 245, 249), (153, 216, 201), (44, 162, 95)],
2245 'bugn4': [(237, 248, 251), (178, 226, 226), (102, 194, 164), (35, 139, 69)],
2246 'bugn5': [(237, 248, 251), (178, 226, 226), (102, 194, 164), (44, 162, 95), (0, 109, 44)],
2247 'bugn6': [(237, 248, 251), (204, 236, 230), (153, 216, 201), (102, 194, 164), (44, 162, 95), (0, 109, 44)],
2248 'bugn7': [(237, 248, 251), (204, 236, 230), (153, 216, 201), (102, 194, 164), (65, 174, 118), (35, 139, 69), (0, 88, 36)],
2249 'bugn8': [(247, 252, 253), (229, 245, 249), (204, 236, 230), (153, 216, 201), (102, 194, 164), (65, 174, 118), (35, 139, 69), (0, 88, 36)],
2250 'bugn9': [(247, 252, 253), (229, 245, 249), (204, 236, 230), (153, 216, 201), (102, 194, 164), (65, 174, 118), (35, 139, 69), (0, 109, 44), (0, 68, 27)],
2251 'bupu3': [(224, 236, 244), (158, 188, 218), (136, 86, 167)],
2252 'bupu4': [(237, 248, 251), (179, 205, 227), (140, 150, 198), (136, 65, 157)],
2253 'bupu5': [(237, 248, 251), (179, 205, 227), (140, 150, 198), (136, 86, 167), (129, 15, 124)],
2254 'bupu6': [(237, 248, 251), (191, 211, 230), (158, 188, 218), (140, 150, 198), (136, 86, 167), (129, 15, 124)],
2255 'bupu7': [(237, 248, 251), (191, 211, 230), (158, 188, 218), (140, 150, 198), (140, 107, 177), (136, 65, 157), (110, 1, 107)],
2256 'bupu8': [(247, 252, 253), (224, 236, 244), (191, 211, 230), (158, 188, 218), (140, 150, 198), (140, 107, 177), (136, 65, 157), (110, 1, 107)],
2257 'bupu9': [(247, 252, 253), (224, 236, 244), (191, 211, 230), (158, 188, 218), (140, 150, 198), (140, 107, 177), (136, 65, 157), (129, 15, 124), (77, 0, 75)],
2258 'dark23': [(27, 158, 119), (217, 95, 2), (117, 112, 179)],
2259 'dark24': [(27, 158, 119), (217, 95, 2), (117, 112, 179), (231, 41, 138)],
2260 'dark25': [(27, 158, 119), (217, 95, 2), (117, 112, 179), (231, 41, 138), (102, 166, 30)],
2261 'dark26': [(27, 158, 119), (217, 95, 2), (117, 112, 179), (231, 41, 138), (102, 166, 30), (230, 171, 2)],
2262 'dark27': [(27, 158, 119), (217, 95, 2), (117, 112, 179), (231, 41, 138), (102, 166, 30), (230, 171, 2), (166, 118, 29)],
2263 'dark28': [(27, 158, 119), (217, 95, 2), (117, 112, 179), (231, 41, 138), (102, 166, 30), (230, 171, 2), (166, 118, 29), (102, 102, 102)],
2264 'gnbu3': [(224, 243, 219), (168, 221, 181), (67, 162, 202)],
2265 'gnbu4': [(240, 249, 232), (186, 228, 188), (123, 204, 196), (43, 140, 190)],
2266 'gnbu5': [(240, 249, 232), (186, 228, 188), (123, 204, 196), (67, 162, 202), (8, 104, 172)],
2267 'gnbu6': [(240, 249, 232), (204, 235, 197), (168, 221, 181), (123, 204, 196), (67, 162, 202), (8, 104, 172)],
2268 'gnbu7': [(240, 249, 232), (204, 235, 197), (168, 221, 181), (123, 204, 196), (78, 179, 211), (43, 140, 190), (8, 88, 158)],
2269 'gnbu8': [(247, 252, 240), (224, 243, 219), (204, 235, 197), (168, 221, 181), (123, 204, 196), (78, 179, 211), (43, 140, 190), (8, 88, 158)],
2270 'gnbu9': [(247, 252, 240), (224, 243, 219), (204, 235, 197), (168, 221, 181), (123, 204, 196), (78, 179, 211), (43, 140, 190), (8, 104, 172), (8, 64, 129)],
2271 'greens3': [(229, 245, 224), (161, 217, 155), (49, 163, 84)],
2272 'greens4': [(237, 248, 233), (186, 228, 179), (116, 196, 118), (35, 139, 69)],
2273 'greens5': [(237, 248, 233), (186, 228, 179), (116, 196, 118), (49, 163, 84), (0, 109, 44)],
2274 'greens6': [(237, 248, 233), (199, 233, 192), (161, 217, 155), (116, 196, 118), (49, 163, 84), (0, 109, 44)],
2275 'greens7': [(237, 248, 233), (199, 233, 192), (161, 217, 155), (116, 196, 118), (65, 171, 93), (35, 139, 69), (0, 90, 50)],
2276 'greens8': [(247, 252, 245), (229, 245, 224), (199, 233, 192), (161, 217, 155), (116, 196, 118), (65, 171, 93), (35, 139, 69), (0, 90, 50)],
2277 'greens9': [(247, 252, 245), (229, 245, 224), (199, 233, 192), (161, 217, 155), (116, 196, 118), (65, 171, 93), (35, 139, 69), (0, 109, 44), (0, 68, 27)],
2278 'greys3': [(240, 240, 240), (189, 189, 189), (99, 99, 99)],
2279 'greys4': [(247, 247, 247), (204, 204, 204), (150, 150, 150), (82, 82, 82)],
2280 'greys5': [(247, 247, 247), (204, 204, 204), (150, 150, 150), (99, 99, 99), (37, 37, 37)],
2281 'greys6': [(247, 247, 247), (217, 217, 217), (189, 189, 189), (150, 150, 150), (99, 99, 99), (37, 37, 37)],
2282 'greys7': [(247, 247, 247), (217, 217, 217), (189, 189, 189), (150, 150, 150), (115, 115, 115), (82, 82, 82), (37, 37, 37)],
2283 'greys8': [(255, 255, 255), (240, 240, 240), (217, 217, 217), (189, 189, 189), (150, 150, 150), (115, 115, 115), (82, 82, 82), (37, 37, 37)],
2284 'greys9': [(255, 255, 255), (240, 240, 240), (217, 217, 217), (189, 189, 189), (150, 150, 150), (115, 115, 115), (82, 82, 82), (37, 37, 37), (0, 0, 0)],
2285 'oranges3': [(254, 230, 206), (253, 174, 107), (230, 85, 13)],
2286 'oranges4': [(254, 237, 222), (253, 190, 133), (253, 141, 60), (217, 71, 1)],
2287 'oranges5': [(254, 237, 222), (253, 190, 133), (253, 141, 60), (230, 85, 13), (166, 54, 3)],
2288 'oranges6': [(254, 237, 222), (253, 208, 162), (253, 174, 107), (253, 141, 60), (230, 85, 13), (166, 54, 3)],
2289 'oranges7': [(254, 237, 222), (253, 208, 162), (253, 174, 107), (253, 141, 60), (241, 105, 19), (217, 72, 1), (140, 45, 4)],
2290 'oranges8': [(255, 245, 235), (254, 230, 206), (253, 208, 162), (253, 174, 107), (253, 141, 60), (241, 105, 19), (217, 72, 1), (140, 45, 4)],
2291 'oranges9': [(255, 245, 235), (254, 230, 206), (253, 208, 162), (253, 174, 107), (253, 141, 60), (241, 105, 19), (217, 72, 1), (166, 54, 3), (127, 39, 4)],
2292 'orrd3': [(254, 232, 200), (253, 187, 132), (227, 74, 51)],
2293 'orrd4': [(254, 240, 217), (253, 204, 138), (252, 141, 89), (215, 48, 31)],
2294 'orrd5': [(254, 240, 217), (253, 204, 138), (252, 141, 89), (227, 74, 51), (179, 0, 0)],
2295 'orrd6': [(254, 240, 217), (253, 212, 158), (253, 187, 132), (252, 141, 89), (227, 74, 51), (179, 0, 0)],
2296 'orrd7': [(254, 240, 217), (253, 212, 158), (253, 187, 132), (252, 141, 89), (239, 101, 72), (215, 48, 31), (153, 0, 0)],
2297 'orrd8': [(255, 247, 236), (254, 232, 200), (253, 212, 158), (253, 187, 132), (252, 141, 89), (239, 101, 72), (215, 48, 31), (153, 0, 0)],
2298 'orrd9': [(255, 247, 236), (254, 232, 200), (253, 212, 158), (253, 187, 132), (252, 141, 89), (239, 101, 72), (215, 48, 31), (179, 0, 0), (127, 0, 0)],
2299 'paired10': [(166, 206, 227), (106, 61, 154), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153), (227, 26, 28), (253, 191, 111), (255, 127, 0), (202, 178, 214)],
2300 'paired11': [(166, 206, 227), (106, 61, 154), (255, 255, 153), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153), (227, 26, 28), (253, 191, 111), (255, 127, 0), (202, 178, 214)],
2301 'paired12': [(166, 206, 227), (106, 61, 154), (255, 255, 153), (177, 89, 40), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153), (227, 26, 28), (253, 191, 111), (255, 127, 0), (202, 178, 214)],
2302 'paired3': [(166, 206, 227), (31, 120, 180), (178, 223, 138)],
2303 'paired4': [(166, 206, 227), (31, 120, 180), (178, 223, 138), (51, 160, 44)],
2304 'paired5': [(166, 206, 227), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153)],
2305 'paired6': [(166, 206, 227), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153), (227, 26, 28)],
2306 'paired7': [(166, 206, 227), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153), (227, 26, 28), (253, 191, 111)],
2307 'paired8': [(166, 206, 227), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153), (227, 26, 28), (253, 191, 111), (255, 127, 0)],
2308 'paired9': [(166, 206, 227), (31, 120, 180), (178, 223, 138), (51, 160, 44), (251, 154, 153), (227, 26, 28), (253, 191, 111), (255, 127, 0), (202, 178, 214)],
2309 'pastel13': [(251, 180, 174), (179, 205, 227), (204, 235, 197)],
2310 'pastel14': [(251, 180, 174), (179, 205, 227), (204, 235, 197), (222, 203, 228)],
2311 'pastel15': [(251, 180, 174), (179, 205, 227), (204, 235, 197), (222, 203, 228), (254, 217, 166)],
2312 'pastel16': [(251, 180, 174), (179, 205, 227), (204, 235, 197), (222, 203, 228), (254, 217, 166), (255, 255, 204)],
2313 'pastel17': [(251, 180, 174), (179, 205, 227), (204, 235, 197), (222, 203, 228), (254, 217, 166), (255, 255, 204), (229, 216, 189)],
2314 'pastel18': [(251, 180, 174), (179, 205, 227), (204, 235, 197), (222, 203, 228), (254, 217, 166), (255, 255, 204), (229, 216, 189), (253, 218, 236)],
2315 'pastel19': [(251, 180, 174), (179, 205, 227), (204, 235, 197), (222, 203, 228), (254, 217, 166), (255, 255, 204), (229, 216, 189), (253, 218, 236), (242, 242, 242)],
2316 'pastel23': [(179, 226, 205), (253, 205, 172), (203, 213, 232)],
2317 'pastel24': [(179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228)],
2318 'pastel25': [(179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228), (230, 245, 201)],
2319 'pastel26': [(179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228), (230, 245, 201), (255, 242, 174)],
2320 'pastel27': [(179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228), (230, 245, 201), (255, 242, 174), (241, 226, 204)],
2321 'pastel28': [(179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228), (230, 245, 201), (255, 242, 174), (241, 226, 204), (204, 204, 204)],
2322 'piyg10': [(142, 1, 82), (39, 100, 25), (197, 27, 125), (222, 119, 174), (241, 182, 218), (253, 224, 239), (230, 245, 208), (184, 225, 134), (127, 188, 65), (77, 146, 33)],
2323 'piyg11': [(142, 1, 82), (77, 146, 33), (39, 100, 25), (197, 27, 125), (222, 119, 174), (241, 182, 218), (253, 224, 239), (247, 247, 247), (230, 245, 208), (184, 225, 134), (127, 188, 65)],
2324 'piyg3': [(233, 163, 201), (247, 247, 247), (161, 215, 106)],
2325 'piyg4': [(208, 28, 139), (241, 182, 218), (184, 225, 134), (77, 172, 38)],
2326 'piyg5': [(208, 28, 139), (241, 182, 218), (247, 247, 247), (184, 225, 134), (77, 172, 38)],
2327 'piyg6': [(197, 27, 125), (233, 163, 201), (253, 224, 239), (230, 245, 208), (161, 215, 106), (77, 146, 33)],
2328 'piyg7': [(197, 27, 125), (233, 163, 201), (253, 224, 239), (247, 247, 247), (230, 245, 208), (161, 215, 106), (77, 146, 33)],
2329 'piyg8': [(197, 27, 125), (222, 119, 174), (241, 182, 218), (253, 224, 239), (230, 245, 208), (184, 225, 134), (127, 188, 65), (77, 146, 33)],
2330 'piyg9': [(197, 27, 125), (222, 119, 174), (241, 182, 218), (253, 224, 239), (247, 247, 247), (230, 245, 208), (184, 225, 134), (127, 188, 65), (77, 146, 33)],
2331 'prgn10': [(64, 0, 75), (0, 68, 27), (118, 42, 131), (153, 112, 171), (194, 165, 207), (231, 212, 232), (217, 240, 211), (166, 219, 160), (90, 174, 97), (27, 120, 55)],
2332 'prgn11': [(64, 0, 75), (27, 120, 55), (0, 68, 27), (118, 42, 131), (153, 112, 171), (194, 165, 207), (231, 212, 232), (247, 247, 247), (217, 240, 211), (166, 219, 160), (90, 174, 97)],
2333 'prgn3': [(175, 141, 195), (247, 247, 247), (127, 191, 123)],
2334 'prgn4': [(123, 50, 148), (194, 165, 207), (166, 219, 160), (0, 136, 55)],
2335 'prgn5': [(123, 50, 148), (194, 165, 207), (247, 247, 247), (166, 219, 160), (0, 136, 55)],
2336 'prgn6': [(118, 42, 131), (175, 141, 195), (231, 212, 232), (217, 240, 211), (127, 191, 123), (27, 120, 55)],
2337 'prgn7': [(118, 42, 131), (175, 141, 195), (231, 212, 232), (247, 247, 247), (217, 240, 211), (127, 191, 123), (27, 120, 55)],
2338 'prgn8': [(118, 42, 131), (153, 112, 171), (194, 165, 207), (231, 212, 232), (217, 240, 211), (166, 219, 160), (90, 174, 97), (27, 120, 55)],
2339 'prgn9': [(118, 42, 131), (153, 112, 171), (194, 165, 207), (231, 212, 232), (247, 247, 247), (217, 240, 211), (166, 219, 160), (90, 174, 97), (27, 120, 55)],
2340 'pubu3': [(236, 231, 242), (166, 189, 219), (43, 140, 190)],
2341 'pubu4': [(241, 238, 246), (189, 201, 225), (116, 169, 207), (5, 112, 176)],
2342 'pubu5': [(241, 238, 246), (189, 201, 225), (116, 169, 207), (43, 140, 190), (4, 90, 141)],
2343 'pubu6': [(241, 238, 246), (208, 209, 230), (166, 189, 219), (116, 169, 207), (43, 140, 190), (4, 90, 141)],
2344 'pubu7': [(241, 238, 246), (208, 209, 230), (166, 189, 219), (116, 169, 207), (54, 144, 192), (5, 112, 176), (3, 78, 123)],
2345 'pubu8': [(255, 247, 251), (236, 231, 242), (208, 209, 230), (166, 189, 219), (116, 169, 207), (54, 144, 192), (5, 112, 176), (3, 78, 123)],
2346 'pubu9': [(255, 247, 251), (236, 231, 242), (208, 209, 230), (166, 189, 219), (116, 169, 207), (54, 144, 192), (5, 112, 176), (4, 90, 141), (2, 56, 88)],
2347 'pubugn3': [(236, 226, 240), (166, 189, 219), (28, 144, 153)],
2348 'pubugn4': [(246, 239, 247), (189, 201, 225), (103, 169, 207), (2, 129, 138)],
2349 'pubugn5': [(246, 239, 247), (189, 201, 225), (103, 169, 207), (28, 144, 153), (1, 108, 89)],
2350 'pubugn6': [(246, 239, 247), (208, 209, 230), (166, 189, 219), (103, 169, 207), (28, 144, 153), (1, 108, 89)],
2351 'pubugn7': [(246, 239, 247), (208, 209, 230), (166, 189, 219), (103, 169, 207), (54, 144, 192), (2, 129, 138), (1, 100, 80)],
2352 'pubugn8': [(255, 247, 251), (236, 226, 240), (208, 209, 230), (166, 189, 219), (103, 169, 207), (54, 144, 192), (2, 129, 138), (1, 100, 80)],
2353 'pubugn9': [(255, 247, 251), (236, 226, 240), (208, 209, 230), (166, 189, 219), (103, 169, 207), (54, 144, 192), (2, 129, 138), (1, 108, 89), (1, 70, 54)],
2354 'puor10': [(127, 59, 8), (45, 0, 75), (179, 88, 6), (224, 130, 20), (253, 184, 99), (254, 224, 182), (216, 218, 235), (178, 171, 210), (128, 115, 172), (84, 39, 136)],
2355 'puor11': [(127, 59, 8), (84, 39, 136), (45, 0, 75), (179, 88, 6), (224, 130, 20), (253, 184, 99), (254, 224, 182), (247, 247, 247), (216, 218, 235), (178, 171, 210), (128, 115, 172)],
2356 'puor3': [(241, 163, 64), (247, 247, 247), (153, 142, 195)],
2357 'puor4': [(230, 97, 1), (253, 184, 99), (178, 171, 210), (94, 60, 153)],
2358 'puor5': [(230, 97, 1), (253, 184, 99), (247, 247, 247), (178, 171, 210), (94, 60, 153)],
2359 'puor6': [(179, 88, 6), (241, 163, 64), (254, 224, 182), (216, 218, 235), (153, 142, 195), (84, 39, 136)],
2360 'puor7': [(179, 88, 6), (241, 163, 64), (254, 224, 182), (247, 247, 247), (216, 218, 235), (153, 142, 195), (84, 39, 136)],
2361 'puor8': [(179, 88, 6), (224, 130, 20), (253, 184, 99), (254, 224, 182), (216, 218, 235), (178, 171, 210), (128, 115, 172), (84, 39, 136)],
2362 'puor9': [(179, 88, 6), (224, 130, 20), (253, 184, 99), (254, 224, 182), (247, 247, 247), (216, 218, 235), (178, 171, 210), (128, 115, 172), (84, 39, 136)],
2363 'purd3': [(231, 225, 239), (201, 148, 199), (221, 28, 119)],
2364 'purd4': [(241, 238, 246), (215, 181, 216), (223, 101, 176), (206, 18, 86)],
2365 'purd5': [(241, 238, 246), (215, 181, 216), (223, 101, 176), (221, 28, 119), (152, 0, 67)],
2366 'purd6': [(241, 238, 246), (212, 185, 218), (201, 148, 199), (223, 101, 176), (221, 28, 119), (152, 0, 67)],
2367 'purd7': [(241, 238, 246), (212, 185, 218), (201, 148, 199), (223, 101, 176), (231, 41, 138), (206, 18, 86), (145, 0, 63)],
2368 'purd8': [(247, 244, 249), (231, 225, 239), (212, 185, 218), (201, 148, 199), (223, 101, 176), (231, 41, 138), (206, 18, 86), (145, 0, 63)],
2369 'purd9': [(247, 244, 249), (231, 225, 239), (212, 185, 218), (201, 148, 199), (223, 101, 176), (231, 41, 138), (206, 18, 86), (152, 0, 67), (103, 0, 31)],
2370 'purples3': [(239, 237, 245), (188, 189, 220), (117, 107, 177)],
2371 'purples4': [(242, 240, 247), (203, 201, 226), (158, 154, 200), (106, 81, 163)],
2372 'purples5': [(242, 240, 247), (203, 201, 226), (158, 154, 200), (117, 107, 177), (84, 39, 143)],
2373 'purples6': [(242, 240, 247), (218, 218, 235), (188, 189, 220), (158, 154, 200), (117, 107, 177), (84, 39, 143)],
2374 'purples7': [(242, 240, 247), (218, 218, 235), (188, 189, 220), (158, 154, 200), (128, 125, 186), (106, 81, 163), (74, 20, 134)],
2375 'purples8': [(252, 251, 253), (239, 237, 245), (218, 218, 235), (188, 189, 220), (158, 154, 200), (128, 125, 186), (106, 81, 163), (74, 20, 134)],
2376 'purples9': [(252, 251, 253), (239, 237, 245), (218, 218, 235), (188, 189, 220), (158, 154, 200), (128, 125, 186), (106, 81, 163), (84, 39, 143), (63, 0, 125)],
2377 'rdbu10': [(103, 0, 31), (5, 48, 97), (178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (209, 229, 240), (146, 197, 222), (67, 147, 195), (33, 102, 172)],
2378 'rdbu11': [(103, 0, 31), (33, 102, 172), (5, 48, 97), (178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (247, 247, 247), (209, 229, 240), (146, 197, 222), (67, 147, 195)],
2379 'rdbu3': [(239, 138, 98), (247, 247, 247), (103, 169, 207)],
2380 'rdbu4': [(202, 0, 32), (244, 165, 130), (146, 197, 222), (5, 113, 176)],
2381 'rdbu5': [(202, 0, 32), (244, 165, 130), (247, 247, 247), (146, 197, 222), (5, 113, 176)],
2382 'rdbu6': [(178, 24, 43), (239, 138, 98), (253, 219, 199), (209, 229, 240), (103, 169, 207), (33, 102, 172)],
2383 'rdbu7': [(178, 24, 43), (239, 138, 98), (253, 219, 199), (247, 247, 247), (209, 229, 240), (103, 169, 207), (33, 102, 172)],
2384 'rdbu8': [(178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (209, 229, 240), (146, 197, 222), (67, 147, 195), (33, 102, 172)],
2385 'rdbu9': [(178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (247, 247, 247), (209, 229, 240), (146, 197, 222), (67, 147, 195), (33, 102, 172)],
2386 'rdgy10': [(103, 0, 31), (26, 26, 26), (178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (224, 224, 224), (186, 186, 186), (135, 135, 135), (77, 77, 77)],
2387 'rdgy11': [(103, 0, 31), (77, 77, 77), (26, 26, 26), (178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (255, 255, 255), (224, 224, 224), (186, 186, 186), (135, 135, 135)],
2388 'rdgy3': [(239, 138, 98), (255, 255, 255), (153, 153, 153)],
2389 'rdgy4': [(202, 0, 32), (244, 165, 130), (186, 186, 186), (64, 64, 64)],
2390 'rdgy5': [(202, 0, 32), (244, 165, 130), (255, 255, 255), (186, 186, 186), (64, 64, 64)],
2391 'rdgy6': [(178, 24, 43), (239, 138, 98), (253, 219, 199), (224, 224, 224), (153, 153, 153), (77, 77, 77)],
2392 'rdgy7': [(178, 24, 43), (239, 138, 98), (253, 219, 199), (255, 255, 255), (224, 224, 224), (153, 153, 153), (77, 77, 77)],
2393 'rdgy8': [(178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (224, 224, 224), (186, 186, 186), (135, 135, 135), (77, 77, 77)],
2394 'rdgy9': [(178, 24, 43), (214, 96, 77), (244, 165, 130), (253, 219, 199), (255, 255, 255), (224, 224, 224), (186, 186, 186), (135, 135, 135), (77, 77, 77)],
2395 'rdpu3': [(253, 224, 221), (250, 159, 181), (197, 27, 138)],
2396 'rdpu4': [(254, 235, 226), (251, 180, 185), (247, 104, 161), (174, 1, 126)],
2397 'rdpu5': [(254, 235, 226), (251, 180, 185), (247, 104, 161), (197, 27, 138), (122, 1, 119)],
2398 'rdpu6': [(254, 235, 226), (252, 197, 192), (250, 159, 181), (247, 104, 161), (197, 27, 138), (122, 1, 119)],
2399 'rdpu7': [(254, 235, 226), (252, 197, 192), (250, 159, 181), (247, 104, 161), (221, 52, 151), (174, 1, 126), (122, 1, 119)],
2400 'rdpu8': [(255, 247, 243), (253, 224, 221), (252, 197, 192), (250, 159, 181), (247, 104, 161), (221, 52, 151), (174, 1, 126), (122, 1, 119)],
2401 'rdpu9': [(255, 247, 243), (253, 224, 221), (252, 197, 192), (250, 159, 181), (247, 104, 161), (221, 52, 151), (174, 1, 126), (122, 1, 119), (73, 0, 106)],
2402 'rdylbu10': [(165, 0, 38), (49, 54, 149), (215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 144), (224, 243, 248), (171, 217, 233), (116, 173, 209), (69, 117, 180)],
2403 'rdylbu11': [(165, 0, 38), (69, 117, 180), (49, 54, 149), (215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 144), (255, 255, 191), (224, 243, 248), (171, 217, 233), (116, 173, 209)],
2404 'rdylbu3': [(252, 141, 89), (255, 255, 191), (145, 191, 219)],
2405 'rdylbu4': [(215, 25, 28), (253, 174, 97), (171, 217, 233), (44, 123, 182)],
2406 'rdylbu5': [(215, 25, 28), (253, 174, 97), (255, 255, 191), (171, 217, 233), (44, 123, 182)],
2407 'rdylbu6': [(215, 48, 39), (252, 141, 89), (254, 224, 144), (224, 243, 248), (145, 191, 219), (69, 117, 180)],
2408 'rdylbu7': [(215, 48, 39), (252, 141, 89), (254, 224, 144), (255, 255, 191), (224, 243, 248), (145, 191, 219), (69, 117, 180)],
2409 'rdylbu8': [(215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 144), (224, 243, 248), (171, 217, 233), (116, 173, 209), (69, 117, 180)],
2410 'rdylbu9': [(215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 144), (255, 255, 191), (224, 243, 248), (171, 217, 233), (116, 173, 209), (69, 117, 180)],
2411 'rdylgn10': [(165, 0, 38), (0, 104, 55), (215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 139), (217, 239, 139), (166, 217, 106), (102, 189, 99), (26, 152, 80)],
2412 'rdylgn11': [(165, 0, 38), (26, 152, 80), (0, 104, 55), (215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 139), (255, 255, 191), (217, 239, 139), (166, 217, 106), (102, 189, 99)],
2413 'rdylgn3': [(252, 141, 89), (255, 255, 191), (145, 207, 96)],
2414 'rdylgn4': [(215, 25, 28), (253, 174, 97), (166, 217, 106), (26, 150, 65)],
2415 'rdylgn5': [(215, 25, 28), (253, 174, 97), (255, 255, 191), (166, 217, 106), (26, 150, 65)],
2416 'rdylgn6': [(215, 48, 39), (252, 141, 89), (254, 224, 139), (217, 239, 139), (145, 207, 96), (26, 152, 80)],
2417 'rdylgn7': [(215, 48, 39), (252, 141, 89), (254, 224, 139), (255, 255, 191), (217, 239, 139), (145, 207, 96), (26, 152, 80)],
2418 'rdylgn8': [(215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 139), (217, 239, 139), (166, 217, 106), (102, 189, 99), (26, 152, 80)],
2419 'rdylgn9': [(215, 48, 39), (244, 109, 67), (253, 174, 97), (254, 224, 139), (255, 255, 191), (217, 239, 139), (166, 217, 106), (102, 189, 99), (26, 152, 80)],
2420 'reds3': [(254, 224, 210), (252, 146, 114), (222, 45, 38)],
2421 'reds4': [(254, 229, 217), (252, 174, 145), (251, 106, 74), (203, 24, 29)],
2422 'reds5': [(254, 229, 217), (252, 174, 145), (251, 106, 74), (222, 45, 38), (165, 15, 21)],
2423 'reds6': [(254, 229, 217), (252, 187, 161), (252, 146, 114), (251, 106, 74), (222, 45, 38), (165, 15, 21)],
2424 'reds7': [(254, 229, 217), (252, 187, 161), (252, 146, 114), (251, 106, 74), (239, 59, 44), (203, 24, 29), (153, 0, 13)],
2425 'reds8': [(255, 245, 240), (254, 224, 210), (252, 187, 161), (252, 146, 114), (251, 106, 74), (239, 59, 44), (203, 24, 29), (153, 0, 13)],
2426 'reds9': [(255, 245, 240), (254, 224, 210), (252, 187, 161), (252, 146, 114), (251, 106, 74), (239, 59, 44), (203, 24, 29), (165, 15, 21), (103, 0, 13)],
2427 'set13': [(228, 26, 28), (55, 126, 184), (77, 175, 74)],
2428 'set14': [(228, 26, 28), (55, 126, 184), (77, 175, 74), (152, 78, 163)],
2429 'set15': [(228, 26, 28), (55, 126, 184), (77, 175, 74), (152, 78, 163), (255, 127, 0)],
2430 'set16': [(228, 26, 28), (55, 126, 184), (77, 175, 74), (152, 78, 163), (255, 127, 0), (255, 255, 51)],
2431 'set17': [(228, 26, 28), (55, 126, 184), (77, 175, 74), (152, 78, 163), (255, 127, 0), (255, 255, 51), (166, 86, 40)],
2432 'set18': [(228, 26, 28), (55, 126, 184), (77, 175, 74), (152, 78, 163), (255, 127, 0), (255, 255, 51), (166, 86, 40), (247, 129, 191)],
2433 'set19': [(228, 26, 28), (55, 126, 184), (77, 175, 74), (152, 78, 163), (255, 127, 0), (255, 255, 51), (166, 86, 40), (247, 129, 191), (153, 153, 153)],
2434 'set23': [(102, 194, 165), (252, 141, 98), (141, 160, 203)],
2435 'set24': [(102, 194, 165), (252, 141, 98), (141, 160, 203), (231, 138, 195)],
2436 'set25': [(102, 194, 165), (252, 141, 98), (141, 160, 203), (231, 138, 195), (166, 216, 84)],
2437 'set26': [(102, 194, 165), (252, 141, 98), (141, 160, 203), (231, 138, 195), (166, 216, 84), (255, 217, 47)],
2438 'set27': [(102, 194, 165), (252, 141, 98), (141, 160, 203), (231, 138, 195), (166, 216, 84), (255, 217, 47), (229, 196, 148)],
2439 'set28': [(102, 194, 165), (252, 141, 98), (141, 160, 203), (231, 138, 195), (166, 216, 84), (255, 217, 47), (229, 196, 148), (179, 179, 179)],
2440 'set310': [(141, 211, 199), (188, 128, 189), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211), (253, 180, 98), (179, 222, 105), (252, 205, 229), (217, 217, 217)],
2441 'set311': [(141, 211, 199), (188, 128, 189), (204, 235, 197), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211), (253, 180, 98), (179, 222, 105), (252, 205, 229), (217, 217, 217)],
2442 'set312': [(141, 211, 199), (188, 128, 189), (204, 235, 197), (255, 237, 111), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211), (253, 180, 98), (179, 222, 105), (252, 205, 229), (217, 217, 217)],
2443 'set33': [(141, 211, 199), (255, 255, 179), (190, 186, 218)],
2444 'set34': [(141, 211, 199), (255, 255, 179), (190, 186, 218), (251, 128, 114)],
2445 'set35': [(141, 211, 199), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211)],
2446 'set36': [(141, 211, 199), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211), (253, 180, 98)],
2447 'set37': [(141, 211, 199), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211), (253, 180, 98), (179, 222, 105)],
2448 'set38': [(141, 211, 199), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211), (253, 180, 98), (179, 222, 105), (252, 205, 229)],
2449 'set39': [(141, 211, 199), (255, 255, 179), (190, 186, 218), (251, 128, 114), (128, 177, 211), (253, 180, 98), (179, 222, 105), (252, 205, 229), (217, 217, 217)],
2450 'spectral10': [(158, 1, 66), (94, 79, 162), (213, 62, 79), (244, 109, 67), (253, 174, 97), (254, 224, 139), (230, 245, 152), (171, 221, 164), (102, 194, 165), (50, 136, 189)],
2451 'spectral11': [(158, 1, 66), (50, 136, 189), (94, 79, 162), (213, 62, 79), (244, 109, 67), (253, 174, 97), (254, 224, 139), (255, 255, 191), (230, 245, 152), (171, 221, 164), (102, 194, 165)],
2452 'spectral3': [(252, 141, 89), (255, 255, 191), (153, 213, 148)],
2453 'spectral4': [(215, 25, 28), (253, 174, 97), (171, 221, 164), (43, 131, 186)],
2454 'spectral5': [(215, 25, 28), (253, 174, 97), (255, 255, 191), (171, 221, 164), (43, 131, 186)],
2455 'spectral6': [(213, 62, 79), (252, 141, 89), (254, 224, 139), (230, 245, 152), (153, 213, 148), (50, 136, 189)],
2456 'spectral7': [(213, 62, 79), (252, 141, 89), (254, 224, 139), (255, 255, 191), (230, 245, 152), (153, 213, 148), (50, 136, 189)],
2457 'spectral8': [(213, 62, 79), (244, 109, 67), (253, 174, 97), (254, 224, 139), (230, 245, 152), (171, 221, 164), (102, 194, 165), (50, 136, 189)],
2458 'spectral9': [(213, 62, 79), (244, 109, 67), (253, 174, 97), (254, 224, 139), (255, 255, 191), (230, 245, 152), (171, 221, 164), (102, 194, 165), (50, 136, 189)],
2459 'ylgn3': [(247, 252, 185), (173, 221, 142), (49, 163, 84)],
2460 'ylgn4': [(255, 255, 204), (194, 230, 153), (120, 198, 121), (35, 132, 67)],
2461 'ylgn5': [(255, 255, 204), (194, 230, 153), (120, 198, 121), (49, 163, 84), (0, 104, 55)],
2462 'ylgn6': [(255, 255, 204), (217, 240, 163), (173, 221, 142), (120, 198, 121), (49, 163, 84), (0, 104, 55)],
2463 'ylgn7': [(255, 255, 204), (217, 240, 163), (173, 221, 142), (120, 198, 121), (65, 171, 93), (35, 132, 67), (0, 90, 50)],
2464 'ylgn8': [(255, 255, 229), (247, 252, 185), (217, 240, 163), (173, 221, 142), (120, 198, 121), (65, 171, 93), (35, 132, 67), (0, 90, 50)],
2465 'ylgn9': [(255, 255, 229), (247, 252, 185), (217, 240, 163), (173, 221, 142), (120, 198, 121), (65, 171, 93), (35, 132, 67), (0, 104, 55), (0, 69, 41)],
2466 'ylgnbu3': [(237, 248, 177), (127, 205, 187), (44, 127, 184)],
2467 'ylgnbu4': [(255, 255, 204), (161, 218, 180), (65, 182, 196), (34, 94, 168)],
2468 'ylgnbu5': [(255, 255, 204), (161, 218, 180), (65, 182, 196), (44, 127, 184), (37, 52, 148)],
2469 'ylgnbu6': [(255, 255, 204), (199, 233, 180), (127, 205, 187), (65, 182, 196), (44, 127, 184), (37, 52, 148)],
2470 'ylgnbu7': [(255, 255, 204), (199, 233, 180), (127, 205, 187), (65, 182, 196), (29, 145, 192), (34, 94, 168), (12, 44, 132)],
2471 'ylgnbu8': [(255, 255, 217), (237, 248, 177), (199, 233, 180), (127, 205, 187), (65, 182, 196), (29, 145, 192), (34, 94, 168), (12, 44, 132)],
2472 'ylgnbu9': [(255, 255, 217), (237, 248, 177), (199, 233, 180), (127, 205, 187), (65, 182, 196), (29, 145, 192), (34, 94, 168), (37, 52, 148), (8, 29, 88)],
2473 'ylorbr3': [(255, 247, 188), (254, 196, 79), (217, 95, 14)],
2474 'ylorbr4': [(255, 255, 212), (254, 217, 142), (254, 153, 41), (204, 76, 2)],
2475 'ylorbr5': [(255, 255, 212), (254, 217, 142), (254, 153, 41), (217, 95, 14), (153, 52, 4)],
2476 'ylorbr6': [(255, 255, 212), (254, 227, 145), (254, 196, 79), (254, 153, 41), (217, 95, 14), (153, 52, 4)],
2477 'ylorbr7': [(255, 255, 212), (254, 227, 145), (254, 196, 79), (254, 153, 41), (236, 112, 20), (204, 76, 2), (140, 45, 4)],
2478 'ylorbr8': [(255, 255, 229), (255, 247, 188), (254, 227, 145), (254, 196, 79), (254, 153, 41), (236, 112, 20), (204, 76, 2), (140, 45, 4)],
2479 'ylorbr9': [(255, 255, 229), (255, 247, 188), (254, 227, 145), (254, 196, 79), (254, 153, 41), (236, 112, 20), (204, 76, 2), (153, 52, 4), (102, 37, 6)],
2480 'ylorrd3': [(255, 237, 160), (254, 178, 76), (240, 59, 32)],
2481 'ylorrd4': [(255, 255, 178), (254, 204, 92), (253, 141, 60), (227, 26, 28)],
2482 'ylorrd5': [(255, 255, 178), (254, 204, 92), (253, 141, 60), (240, 59, 32), (189, 0, 38)],
2483 'ylorrd6': [(255, 255, 178), (254, 217, 118), (254, 178, 76), (253, 141, 60), (240, 59, 32), (189, 0, 38)],
2484 'ylorrd7': [(255, 255, 178), (254, 217, 118), (254, 178, 76), (253, 141, 60), (252, 78, 42), (227, 26, 28), (177, 0, 38)],
2485 'ylorrd8': [(255, 255, 204), (255, 237, 160), (254, 217, 118), (254, 178, 76), (253, 141, 60), (252, 78, 42), (227, 26, 28), (177, 0, 38)],
2489 if __name__ ==
'__main__':