Русские Блоги
Установка Graphviz и вводное руководство под windows
Поскольку используется дерево решений глубокого обучения, необходимо интуитивно экспортировать файл .dot в виде графа. Итак, вам нужно использовать graphviz.
Адрес для перепечатки: http://blog.csdn.net/lanchunhui/article/details/49472949
- Загрузите и установите переменные среды конфигурации
- intall
- Настроить переменные среды
- проверка
- graph
- digraph
- Сложный пример
Обнаружение хороших инструментов похоже на открытие нового мира. Иногда нам будет любопытно, как сделать такие яркие иллюстрации в бумагах и книгах всех без исключения профессий без умелого использования рисовальных инструментов.
Скачать, установить, настроить переменные среды
intall

Двойной клик msi File, а затем перейдите к следующему (запомните путь установки, путь по умолчанию — C: \ Program Files (x86) \ Graphviz2.38, информация о пути будет использоваться для настройки переменных среды позже), после завершения установки, в меню «Пуск» Windows будет создано сообщение с ярлыком. Ярлык по умолчанию не размещается на рабочем столе. Чтобы

Настроить переменные среды
Добавьте папку bin в каталоге установки graphviz в переменную среды Path:


проверка
Войдите в интерфейс командной строки Windows, введите dot -version , А затем нажмите Enter.Если отображается соответствующая информация о версии graphviz, установка и настройка выполнены успешно.

Используйте команду в окне cmd, чтобы преобразовать точечный файл в графический файл pdf.
Вам нужно ввести преобразованный путь к файлу, иначе вы не знаете, куда идти.
dot -Tpdf D:\mycodes\pythonStudy\python\allDecisionTree.dot -o D:\mycodes\pythonStudy\python\allDecisionTree.pdf
Начало работы с основным рисунком
Откройте редактор graphviz под окнами gvedit , Напишите следующий язык сценариев с точкой и сохраните его как текстовый файл в формате gv. Затем войдите в интерфейс командной строки и используйте команду с точкой, чтобы преобразовать файл gv в графический файл png.
graph
использование графика — Опишите отношения

digraph
использовать -> Опишите отношения

Сложный пример

Взаимодействовать с python
Мощный и удобный метод Graphviz для рисования диаграмм / блок-схем позволяет нам легко думать о машинном обучении. Decision Tree Метод отображения. К счастью, scikit-learn предоставляет .dot Файловый интерфейс, конкретные операции следующие:
LinuxShare
Однажды, собираясь писать документацию — я задумался. Проект, который я собирался документировать, динамически развивался и было очевидно, что все схемы, которые я буду рисовать ещё не раз придётся дополнять и перерисовывать. «Вот бы было что-то типа Wiki, но с возможностью также легко рисовать схемы» — подумал тогда я. «Но неужели до меня никто не додумался до столь простой мысли и не сделал столь полезного изобретения?» — меня посетили сомнения. «Не может быть!» Я отправился в поисковые системы, где во множестве предлагались различные платные графические редакторы, позволяющие рисовать прямо в браузере. Но тут мой взгляд зацепился за знакомое название GraphViz! Вспомнив, что я уже не раз слышал об этом продукте, а также не раз видел его в составе моего дистрибутива, я решил познакомится поближе и неожиданно увлёкся.
Автор статьи: Виктор Вислобоков
Размещается под лицензией: CC-BY-NC-NDУстановка
Установка до безобразия проста. GraphViz входит в состав практически всех извесных мне дистрибутивов, ориентированных на пользователя. Так что всё что остаётся, например, людям использующим Fedora, CentOS и прочие rpm-дистрибутивы с yum, это выполнить команду:
Также в дистрибутивах есть пакеты, позволяющие использовать GraphViz со многими языками прогаммирования: Perl, Python, PHP, Tcl/TK и и.д. Возможно после ознакомления с GraphViz вы захотите поставить и использовать также и эти пакеты.
Первое использование
Использовать GraphViz очень просто. Как всегда всё в стиле Unix-way, т.е. через командную строку. Вы делаете файл, в котором, на некоем мета-языке содержится описание требуемого вам графа, а затем запускаете утилиту из комплекта GraphViz, которая из этого файла делает другой файл, хранящий в себе уже сам отрисованный граф.
Простейший пример. Сделаем файл example1.gv вида: и получим из него картинку в формате PNG:

Думаю, теперь вы уже можете без труда составить простейшие вертикальные графы.
Разумеется, отрисованный граф можно получать не только в виде PNG-картинки. Это может быть и SVG-графика, встраиваемая в веб-страницу, и PDF, и PostScript, VML и т.д. и т.д.
Разумеется, GraphViz может много больше, чем просто отрисовка столь примитивного графа, который был продемонстрирован в предыдущем разделе. Возможностей очень много и их полное описание выходит за пределы данной статьи. Если вы очень любите изучать всё с начала и до конца, то я рекомендую посетить официацльный сайт на предмет чтения официальной документации: http://www.graphviz.org. Я же рассмотрю лишь некоторые полезные возможности, которые помогут вам начать рисовать достаточно продвинутые графы и схемы.
Немного теории
Хотя с помощью GraphViz можно рисовать схемы, которые лишь отдалённо напоминают графы, всё же GraphViz — это именно средство для отрисовки графов! Поэтому не ждите от неё возможностей Visio или чего-то подобного, у этого продукта (как впрочем и любого другого) есть свои ограничения и недостатки, о чём будет сказано ниже. И вот вам кстати ссылка на Галерею графов, где вы можете посмотреть, что можно получить с помощью GraphViz.
Прежде чем пойти дальше, я введу некоторые термины, которыми мы будем оперировать. Они пригодятся ниже, когда я буду давать пояснения, а также если вы вдруг всё же начнёте изучать полную документацию. Итак:
- node — Узел графа. Обычно представляет из себя какую-либо фигуру из библиотеки встроенных фигур.
- edge — Переводится как «край», но в GraphViz имеет совсем другое значение. Обычно это стрелка, соединяющая node (узлы графа)
- subgraph — Подграф, который включается в основной граф. Самостоятельная область графа, которая может включать в себя другие узлы и которая затем самостоятельно отрисовывается в графе
- cluster — Или «кластер». Это разновидность подграфа, которая может иметь метку и выделенную область, выделяемую цветом.
- атрибут — Именованный параметр, который может изменять оформление или поведение графа, подграфа, node или edge. Атрибутов великое множество и подробное описание к ним можно найти на официальном сайте, ссылку на который я уже приводил.
Имена узлов
GraphViz по умолчанию заточен на использование UTF-8 и вы можете преспокойно использовать русские буквы в названии узлов графа. Единственное, что необходимо помнить, что лучше заключайте любые имена в двойные кавычки, хотя GraphViz и позволяет использовать имена из одного слова, не содержащие разделительных знаков без кавычек. Т.е. вы можете использовать следующие имена узлов: Обратите внимание, в двух последних случаях использование двойных кавычек обязательно, потому что в имени «Новый год» два слова, разделённые через пробел, а имя «self-made» содержит служебный символ «-«. В общем мой совет — используйте кавычки всегда и не ошибётесь, а напротив избежите досадных ошибок, связанных с невнимательностью.
В любом месте файла вы можете использовать комментарии также как в языке C++, т.е. либо вот так: либо вот так:
Умолчания
Если вы используете набор однотипных фигур и стрелок, но не тот, который установлен по умолчанию, гораздо удобней будет выставить вначале необходимые умолчания, которые будут действовать для всего графа. Например умолчание: приведёт к тому, что вместо эллипсов, внешний вид узлов примет вид прямоугольников, а все стрелки будут иметь два кончика, указывающие в обоих направлениях.
Примеры
Чтобы не описывать каждый раз подробно один из атрибутов, я просто приведу здесь несколько примеров, комбинируя которые вы и сможете в большинстве случаев получить то, что вам нужно. Примеры, я привожу исходя из того, что когда-то искал сам, так что надеюсь, что вы тоже оцените их полезность
Пример 1. Предположим вы хотите составить себе план действий на неделю, потому что периодически, что-либо вылетает из головы. Например, во вторник и субботу вы моете свой автомобиль, а по понедельникам, четвергам и субботам у вас тренировка в спортзале. А в среду, пятницу и понедельник вам нужно зайти в магазин за продуктами. А в четверг вам ещё нужно побывать в паспортном столе, чтобы забрать документы, а если они ещё будут не готовы, то подождать их сидя в кафе неподалёку. Теперь, сразу решаем, что внешний вид узлов графа должен быть круги вместо эллипсов, которые залиты синим цветом, а надписи в них будут белые. Поскольку документы — это наиболее важное в нашем плане, то мы используем красный цвет. А стрелки мы хотим, чтобы были не сплошные, а пунктирные. Да и граф нужно ориентировать не по вертикали, а по горизонтали, потому что так нам наглядней. В итоге получаем: И картинку:

Уместно дать некоторые пояснения. Как видите, цвет можно задавать не только его названием, но и 16-ричным кодом, как в HTML (#RRGGBB). Единожды появившееся описание узла, используется повсеместно, не вызывая конфликтов. Несвязанные узлы, например «Воскресенье» так и остаются в графе без стрелочек. Атрибут margin=»0.01″ используется, чтобы уменьшить отступ внутри кругов, иначе они будут больше, что не всегда удобно. Атрибут rankdir=»LR» меняет направление графа с «TB» (сверху вниз), на «LR» (слева направо).
Посмотрев на граф, вы видите, что он получился не таким уж и удобным. Дни недели разбросаны по всему графу, ориентироваться в нём неудобно. Может быть попробовать всё же изобразить его вертикально?
Пример 2. Давайте попробуем изобразить ранее изученный пример вертикально. Ну а чтобы было интересней, заключим дни недели в кластер, выделим его цветом и добавим метку. А вместо кругов в качестве фигур для дней недели будем использовать прямоугольники, залитые зелёным цветом. А шрифт у названий дней недели сделаем чёрного цвета и помельче. Заодно ещё и добавим в воскресенье сперва поход в театр, а затем в кафе: и картика:

Думаю, вы уже поняли, почему дни недели вверху выстроены не по порядку. Если нет, то присмотритесь внимательней — GraphViz распределил на графе узлы так, чтобы обеспечить наименьшее пересечение стрелок друг с другом. Пересечение стрелок может запутать, поэтому GraphViz оптимизирует свою работу при построении графа именно так.
Ещё обратите внимание, чтобы была возможность сделать рамочку и подпись к кластеру, имя у подграфа должно начинаться с «cluster» и никак иначе
Пример 3. Теперь давайте возьмём так сказать один день из жизни и сделаем из него блок-схему алгоритма. Пусть это будет четверг. Делаем практически то, что уже пробовали, лишь добавляем к стрелочкам, соединяющим узлы подписи «Да» и «Нет»: получаем картинку:
И. разочаровано на неё смотрим! Коряво получилось. «Кафе» должно быть сбоку от условия «Если готовы документы», а у нас оно внизу, а стрелка к «Кафе» и обратно к «Если готовы документы» идёт совсем не по стандарту. Если изменить уровнь у «Кафе» ещё можно, использовав распределение узлов по уровням, то со стрелками уже ничего поделать нельзя. Вот вам и первый недостаток GraphViz — он не ориентирован на создание прямолинейных блок-схем алгоритмов.Пример 4. Давайте теперь ознакомимся с возможностью GraphViz распределять узлы графа по определённым уровням высоты. Реализована эта возможность, через создание в качестве некой «линейки уровней» ещё одного невидимого графа в стороне от основного и закрепление узлов нашего графа на том же уровне, что узлов линейки. Итак, снова берём наш план и меняем его вот так: В итоге получим вот такую смешную картинку:

Обратите внимание, у узлов линейнки, установлен атрибут: который запрещает отрисовывать эти узлы, хотя и OpenViz резервирует место под них, а атрибут у стрелок, приводит к тому, что они отрисовываются, но белым цветом, таким же как цвет фона, поэтому их не видно!
Как вы можете видеть, теперь дни недели упорядочены по высоте, но к сожалению не находятся друг под другом. И увы, мне неизвесно способа как их можно заставить выстроится именно так! Конструкция: говорит, что узлы «2» и «Вторник» должны находится на одном уровне. Вы можете, например, добавить ещё какой-либо узел после «Вторник» также через «;» и этот узел также будет отрисован на этом же уровне.
Ещё один недостаток такого распределения по уровням становится ясен, когда начинаете работать с кластерами. Я пытался создать в кластере ещё один кластер и несколько узлов, распределив их по высоте, но сколь я не бился — у меня ничего не вышло. По неизвестной мне причине, уровни начинали вставать попарно друг с другом рядом. Если кто знает почему так и как это решить — напишите мне и моё «большое спасибо» вам обеспечено. Заодно дополню статью.
Пример 5. А что если хочется странного, например, чтобы название узла было в две строки? Это как раз довольно просто. А если вдруг хочется чтобы вторая строка имела другой цвет и размер шрифта? Вот это уже гораздо сложнее! А бывает вообще хочется некий прямоугольник, разбитый по секциям с разными надписями. Вот вам пример, реализующий всё вышесказанное: И картинка:

Как видите, если «box1» и «box2» используют тип узла «box» и HTML-форматирование, то «box3», «box4» и «box5» используют специальный тип узла: «record». К сожалению у «record» есть недостаток — расположение меток зависит от направленности графа, т.е. если бы у этого графа атрибут «rankdir» был выставлен в «LR» а не как по умолчанию в «TB», то метки «слева» и «справа» стали бы отрисоваться не слева и справа, а сверху и снизу и наоборот метки «снизу» и «сверху» стали бы отрисовываться вместо снизу и свеху, справа и слева. Это не очень-то удобно, если вы по каким-то причинам решить поменять направление роста графа.
Пример 6. Тем не менее, GraphViz неплохо подходит для отображения структуры баз данных и связей между таблицами. Приведём пример, заодно пользуясь случаем показать, что можно изменить внешний вид наконечников стрелок: и картинка:

Заключение
В общем-то пожалуй и всё, что я хотел рассказать. Думаю, для решения множества задач — этих примеров достаточно.
Хочется заметить, что во всех примерах я использовал направленный граф и утилиту dot, однако GraphViz позволяет использовать и другие виды отрисовки графов, такие как «circo», «neato» и т.д. Так вот, чтобы попробовать отобразить свой граф в таком режиме, нужно вместо dot использовать соответствующую утилиту: circo, neato и т.д. Не все атрибуты, которые поддерживаются dot, поддерживаются другими способами отображения — нужно иметь это в виду.
User Guide¶
graphviz provides a simple pure-Python interface for the Graphviz graph-drawing software. It runs under Python 3.7+. To install it with pip, run the following:
For a system-wide install, this typically requires administrator access. For an isolated install, you can run the same inside a venv or a virtualenv.
After installing Graphviz, make sure that its bin/ subdirectory containing the dot layout command for rendering graph descriptions is on your systems’ PATH (sometimes done by the installer; setting PATH on Linux, Mac, and Windows): On the command-line, dot -V should print the version of your Graphiz installation.
Windows users might want to check the status of known issues (gvedit.exe, sfdp, commands) and consider trying an older archived version as a workaround (e.g. graphviz-2.38.msi).
See the downstream conda-forge distribution conda-forge/python-graphviz (feedstock), which should automatically conda install conda-forge/graphviz (feedstock) as dependency.
Basic usage¶
The graphviz package provides two main classes: graphviz.Graph and graphviz.Digraph . They create graph descriptions in the DOT language for undirected and directed graphs respectively. They have the same API .
Graph and Digraph produce different DOT syntax and have different values for directed .
Create a graph by instantiating a new Graph or Digraph object:
Their constructors allow to set the graph’s name identifier, the filename for the DOT source and the rendered graph, an optional comment for the first source code line, etc.
Add nodes and edges to the graph object using its node() and edge() or edges() methods:
The node() method takes a name identifier as first argument and an optional label . The edge() method takes the names of start node and end node, while edges() takes an iterable of name pairs. Keyword arguments are turned into (node and edge) attributes (see extensive Graphviz docs on available attributes).
Check the generated DOT source code:
Use the render() method to save the DOT source code and render it with the default dot layout engine (see below for using other layout engines).
Passing view=True will automatically open the resulting (PDF, SVG, PNG, etc.) file with your system’s default viewer application for the rendered file type.
Backslash-escapes and strings of the form <. > have a special meaning in the DOT language and are currently passed on as is by this library. If you need to render arbitrary strings literally (e.g. from user input), consider wrapping them with the graphviz.escape() function first. See the sections on Backslash escapes and Quoting and HTML-like labels below for details.
Formats¶
To use a different output file format than the default PDF, you canuse the format argument when creating your Graph or Digraph object:
You can also change the format attribute on an existing graph object:
Piped output¶
To directly access the raw results from the Graphviz dot layout command as binary bytes or as decoded str (for plain-text formats like SVG) instead of writing to a file, use the pipe() method of your Graph or Digraph object:
Because pipe() returns the raw stdout from the layout subprocess by default ( bytes ), you usually want to decode the return value when piping into formats like ‘svg’ or ‘plain’ ,
The output for pipe() is buffered in memory, so avoid this method if the data size is large.
Jupyter notebooks¶
Graph and Digraph objects have a _repr_mimebundle_() method so they can be rendered and displayed directly inside a Jupyter notebook. For an example, check the examples/graphviz-notebook.ipynb file in the source repository/distribution (or the same notebook in nbviewer).
This also allows direct displaying within the Jupyter Qt Console (also the one inside Spyder IDE):

By default _repr_mimebundle_() uses ‘svg’ format. You can use the graphviz.set_jupyter_format() to override the default format that is used for displaying in IPython/Jupyter. (example, nbviewer).
You can also use display_svg() , display_png() , or .display_jpeg() from IPython.display to display the rendered Graph or Digraph as SVG, PNG or JPEG in IPython/Jupyter.
Styling¶
Use the graph_attr , node_attr , and edge_attr arguments of the Graph and Digraph constuctors to change the default attributes for your graph, nodes, and edges.
After creation, the graph_attr , node_attr , and edge_attr attributes be edited on instances:
Attributes¶
To directly add DOT att_stmt attribute statements, call the attr() method of the Graph or Digraph instance with the wanted target as first argument and the attributes as keyword args.
Attribute statements affect all later graphs, nodes, or edges within the same (sub-)graph.
If you omit the first attr() argument, the method can be used to set arbitrary attributes as key-value pairs targeting the current (sub-)graph (e.g. for rankdir , label , or setting rank=’same’ within a subgraph context, example ):
Node ports & compass¶
The edge() and edges() methods use the colon-separated node[:port[:compass]] format for tail and head nodes. This allows to specify an optional node port plus an optional compass point the edge should aim at for the given tail or head node ( example ).
As colons are used to indicate port and compass for edges, node names containing one or more literal colons : are currently not supported. GH #54
There is no such restriction for the label argument, so you can work around by choosing a colon-free name together with the wanted label as demonstrated below
Backslash escapes¶
The Graphviz layout engines support a number of escape sequences such as \n , \l , \r (for placement of multi-line labels: centered, left-justified, right-justified) and \N , \G , \L (expanded to the current node name, graph name, object label). To be able to use them from this library (e.g. for labels), backslashes in strings are (mostly) passed on as is.
This means that literal backslashes need to be escaped (doubled) by the user. As the backslash is also special in Python string literals a second level of doubling is needed. E.g. label=’\\\\’ for a label that is rendered as single literal backlash: \ .
Doubling of backslashes can be avoided by using raw string literals ( r’. ‘ ) instead. This is similar to the solution proposed for the stdlib re module. See also https://en.wikipedia.org/wiki/Leaning_toothpick_syndrome.
To disable any special character meaning in a string (e.g. from user input to be rendered literally), use the graphviz.escape() function (similar to the re.escape() function):
To prevent breaking the internal quoting mechanism, the special meaning of \" as a backslash-escaped quote has been disabled since version 0.14 of this library. E.g. both label=’"’ and label=’\\"’ now produce the same DOT source [label="\""] (a label that renders as a literal quote). See also examples/graphviz-escapes.ipynb (nbviewer).
Quoting and HTML-like labels¶
The graph-building methods of Graph and Digraph objects automatically take care of quoting (and escaping quotes) where needed (whitespace, keywords, double quotes, etc.):
If a string starts with ‘<‘ and ends with ‘>’ , it is passed on as is, i.e. without quoting/escaping: The content between the angle brackets is treated by the Graphviz layout engine as special HTML string that can be used for HTML-like labels:
For strings that should literally begin with ‘<‘ and end with ‘>’ , use the graphviz.nohtml() function to disable the special meaning of angled parenthesis and apply normal quoting/escaping:
Before version 0.8.2 , the only workaround was to add leading or trailing space ( label=’ <>’ ):
Subgraphs & clusters¶
Graph and Digraph objects have a subgraph() method for adding a subgraph to the instance.
There are two ways to use it: Either with a ready-made instance of the same kind as the only argument (whose content is added as a subgraph) or omitting the graph argument (returning a context manager for defining the subgraph content more elegantly within a with -block).
First option, with graph as the only argument:
Second usage, with a with -block (omitting the graph argument):
Both produce the same result:
If the name of a subgraph begins with ‘cluster’ (all lowercase), the layout engine treats it as a special cluster subgraph ( example ). See the Subgraphs and Clusters section in DOT language.
When subgraph() is used as a context manager, the new graph instance is created with strict=None copying the parent graph values for directory , engine , format , renderer , formatter , and encoding :
These copied attributes are only relevant for rendering the subgraph independently (i.e. as a stand-alone graph) from within the with -block.
Engines¶
To use a different layout engine than the default dot when rendering your graph, you can use the engine argument on the constructor of Graph or Digraph .
You can also change the engine attribute on an existing instance:
neato no-op flag¶
The neato layout engine supports an additional rendering flag that allows more control over the node positoning and the edge layout via the pos, overlap, and splines attributes.
Use the neato_no_op keyword argugment of render() or pipe() to pass it to the layout command:
Unflatten¶
To prepocess the DOT source of a Graph or Digraph with the unflatten preprocessor (manpage, PDF), use the unflatten() method.
unflatten() improves the aspect ratio of graphs with many leaves or disconnected nodes.
The method returns a Source object that you can render() , view() , etc. with the same basic API as Graph or Digraph objects (minus modification, see details below ).
Custom DOT statements¶
To add arbitrary statements to the created DOT source, you can use the body attribute of Graph and Digraph objects. It holds the verbatim list of ( str ) lines to be written to the source file (including their final newline). Use its append() or extend() method:
Note that you might need to correctly quote/escape identifiers and strings containing whitespace or other special characters when using this method.
Using raw DOT¶
To render a ready-made DOT source code string (instead of assembling one with the higher-level interface of Graph or Digraph ), create a graphviz.Source object holding your DOT string:
Use the render() method to save and render it:
Apart from lacking editing methods, Source objects have the same basic API as the higher-level Graph and Digraph objects (e.g. save() , render() , view() , pipe() methods, engine and format attributes, Jupyter notebook _repr_mimebundle_() , etc. See API docs ).
Existing files¶
To directly render an existing DOT source file (e.g. created with other tools), you can use the graphviz.render() function.
To directly display the rendered visualization of an existing DOT source file inside a Jupyter notebook or Qt Console, you can use graphviz.Source.from_file() (alternative constructor):

Note that render() and view() on Source instances returned by graphviz.Source.from_file() skip writing the loaded file back. The same holds for save() . The instances resolve default .save(skip_existing=None) to .save(skip_existing_run=True) to skip writing the read source back into the same file (specifically the same path that it was loaded from). Call .save(skip_existing=False) if you want to re-write the loaded source.
Before version 0.18 of this library, Source.save() , Source.render() , and Source.view() , wrote the content read into source back into the file. It was advised to use graphviz.render() and graphviz.view() to directly work on files if the superflous saving needed to be avoided.
Integration with viewers¶
On platforms such as Windows, viewer programs opened by render() with view=True (or eqivalently with the view() shortcut-method) might lock the (PDF, PNG, etc.) file for as long as the viewer is open (blocking re-rendering it with a Permission denied error).