Python
JavaScript
Flask
bioinformatics
Cytoscape

Cytoscape.jsをPython Flaskで呼び出してネットワーク図を描画したり動かしたりしてみた

20181003_cytoscape_qiita.png

JavaScript版のCytoscapeでネットワーク図を綺麗に描画したり動かしたりしたくなり、Pythonの軽量のウェブアプリケーションフレームワークFlaskをはじめて使ってみました。

Flask、HTML、CSS、JavaScriptと全部慣れない中の作業だったので苦労しましたが、なんとか表示させるところまでできました。中でも、Flaskがとてもわかりやすくて助かりました。


準備


1. Flaskをインストール

macOS SierraでHomebrew+pyenv+Anacondaという組み合わせの環境です。

ここにpipでインストール。

$ pip install Flask


2. Cytoscape.jsをダウンロード

git cloneでOK。

$ git clone https://github.com/cytoscape/cytoscape.js.git

ダウンロードするとcytoscape.jsという名前のディレクトリが作られ、その配下にたくさんのファイルが配置されているのがわかります。作るの大変だっただろうなぁ、、、

ツリー構造が長すぎるのですが、興味があればどうぞ

.

├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── benchmark
│   ├── a-star.js
│   ├── add-remove-class.js
│   ├── add-remove.js
│   ├── add.js
│   ├── all
│   │   └── index.js
│   ├── all-are-neighbors.js
│   ├── all-are.js
│   ├── any-same.js
│   ├── bellman-ford.js
│   ├── betweenness-centrality.js
│   ├── bfs.js
│   ├── classes.js
│   ├── closeness-centrality.js
│   ├── collection-creation.js
│   ├── contains.js
│   ├── degree-centrality.js
│   ├── dfs.js
│   ├── dijkstra.js
│   ├── floyd-warshall.js
│   ├── graphs
│   │   ├── abcde.json
│   │   ├── gal.json
│   │   └── random.js
│   ├── has-class.js
│   ├── id-selector.js
│   ├── init.js
│   ├── is.js
│   ├── karger-stein.js
│   ├── kruskal.js
│   ├── page-rank.js
│   ├── same.js
│   ├── selector-filter.js
│   ├── single
│   │   └── index.js
│   └── suite
│   └── index.js
├── bower.json
├── debug
│   ├── add-remove.js
│   ├── bind.js
│   ├── compound.js
│   ├── filter.js
│   ├── images
│   │   ├── favicon.png
│   │   ├── gnu-small.png
│   │   ├── gnu.jpg
│   │   ├── gnu.png
│   │   └── gnu.svg
│   ├── index.html
│   ├── init.js
│   ├── layout.js
│   ├── livereload.js
│   ├── memory.html
│   ├── notify.js
│   ├── style.css
│   ├── style.js
│   ├── tests.js
│   ├── toggles.js
│   └── view.js
├── dist
│   ├── cytoscape.js
│   └── cytoscape.min.js
├── documentation
│   ├── CNAME
│   ├── css
│   │   ├── font-awesome.css
│   │   ├── highlight
│   │   │   ├── arta.css
│   │   │   ├── ascetic.css
│   │   │   ├── atelier-dune.dark.css
│   │   │   ├── atelier-dune.light.css
│   │   │   ├── atelier-forest.dark.css
│   │   │   ├── atelier-forest.light.css
│   │   │   ├── atelier-heath.dark.css
│   │   │   ├── atelier-heath.light.css
│   │   │   ├── atelier-lakeside.dark.css
│   │   │   ├── atelier-lakeside.light.css
│   │   │   ├── atelier-seaside.dark.css
│   │   │   ├── atelier-seaside.light.css
│   │   │   ├── brown_paper.css
│   │   │   ├── brown_papersq.png
│   │   │   ├── dark.css
│   │   │   ├── default.css
│   │   │   ├── docco.css
│   │   │   ├── far.css
│   │   │   ├── foundation.css
│   │   │   ├── github.css
│   │   │   ├── googlecode.css
│   │   │   ├── idea.css
│   │   │   ├── ir_black.css
│   │   │   ├── magula.css
│   │   │   ├── mono-blue.css
│   │   │   ├── monokai.css
│   │   │   ├── monokai_sublime.css
│   │   │   ├── obsidian.css
│   │   │   ├── paraiso.dark.css
│   │   │   ├── paraiso.light.css
│   │   │   ├── pojoaque.css
│   │   │   ├── pojoaque.jpg
│   │   │   ├── railscasts.css
│   │   │   ├── rainbow.css
│   │   │   ├── school_book.css
│   │   │   ├── school_book.png
│   │   │   ├── solarized_dark.css
│   │   │   ├── solarized_light.css
│   │   │   ├── sunburst.css
│   │   │   ├── tomorrow-night-blue.css
│   │   │   ├── tomorrow-night-bright.css
│   │   │   ├── tomorrow-night-eighties.css
│   │   │   ├── tomorrow-night.css
│   │   │   ├── tomorrow.css
│   │   │   ├── vs.css
│   │   │   ├── xcode.css
│   │   │   └── zenburn.css
│   │   ├── hl.min.css
│   │   ├── reset.css
│   │   └── style.css
│   ├── demos
│   │   ├── 0365589fdb70b58af282 -> ./spread-layout
│   │   ├── 04030586763520be8d7a -> ./circle-layout
│   │   ├── 173313aba1f31cae49a5 -> ./pie-style
│   │   ├── 18504640d9a03c178fff -> ./edge-types
│   │   ├── 29419ca0e6430a7185a5 -> ./genemania-export
│   │   ├── 2abfc41c86c1e3cb0700 -> ./labels
│   │   ├── 2ebdc40f1c2540de6cf0 -> ./colajs-graph
│   │   ├── 310dca83ba6970812dd0 -> ./multiple-instances
│   │   ├── 444dc95703caa319c147 -> ./concentric-layout
│   │   ├── 546dd8ca4872cc87106a -> ./qtip-extension
│   │   ├── 57e7cc43342193d9d21a -> ./performance-tuning
│   │   ├── 59e38e9f20e25a293e44 -> ./cose-bilkent-layout-compound
│   │   ├── 5b192c88616af2f75344 -> ./compound-nodes
│   │   ├── 6000-elements
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── 621d51ea7de19608127e -> ./initialisation
│   │   ├── 689efca4fcb0fd05671b -> ./architecture
│   │   ├── 6c9907e7896f8ae23f9f -> ./cose-bilkent-layout
│   │   ├── 7b511e1f48ffd044ad66 -> ./cose-layout
│   │   ├── 7e2f4d29ff7ef1a1bba5 -> ./animated-bfs
│   │   ├── aedff159b0df05ccfaa5 -> ./images-breadthfirst-layout
│   │   ├── animated-bfs
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── architecture
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── b7c65115947d9e0e8ec8 -> ./visual-style
│   │   ├── cde4db55e581d10405f5 -> ./wine-cheese-map
│   │   ├── circle-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cola-compound
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── colajs-graph
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── compound-nodes
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── concentric-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cose-bilkent-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cose-bilkent-layout-compound
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cose-layout
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── dagre-layout
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── e52c2fbc0b09edd6ec46 -> ./dagre-layout
│   │   ├── eb861f83fb741628342f -> ./linkout-example
│   │   ├── edge-types
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── f64e811fc3311414e083 -> ./tokyo-railways
│   │   ├── f70c9e45c43f40f7dfe1 -> ./grid-layout
│   │   ├── genemania-export
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── grid-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── images-breadthfirst-layout
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── initialisation
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── labels
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── linkout-example
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── multiple-instances
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── performance-tuning
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── pie-style
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── qtip-extension
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── spread-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── tokyo-railways
│   │   │   ├── index.html
│   │   │   ├── style.css
│   │   │   └── tokyo-railways.js
│   │   ├── visual-style
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   └── wine-cheese-map
│   │   └── index.html
│   ├── docmaker.js
│   ├── docmaker.json
│   ├── font
│   │   ├── FontAwesome.otf
│   │   ├── fontawesome-webfont.eot
│   │   ├── fontawesome-webfont.svg
│   │   ├── fontawesome-webfont.ttf
│   │   ├── fontawesome-webfont.woff
│   │   └── fontawesome-webfont.woff2
│   ├── img
│   │   ├── cytoscape-logo.png
│   │   ├── cytoscape-logo.svg
│   │   └── demos
│   │   ├── 6000-elements.png
│   │   ├── angularjs-example.png
│   │   ├── animated-bfs.png
│   │   ├── architecture.png
│   │   ├── automove.png
│   │   ├── circle-layout.png
│   │   ├── cola-compound.png
│   │   ├── cola-layout.png
│   │   ├── colajs-graph.png
│   │   ├── compound-nodes.png
│   │   ├── concentric-layout.png
│   │   ├── cose-bilkent-layout-compound.png
│   │   ├── cose-bilkent-layout.png
│   │   ├── cose-layout.png
│   │   ├── cxtmenu.png
│   │   ├── dagre-layout.png
│   │   ├── edge-types.png
│   │   ├── edgehandles.png
│   │   ├── euler-layout.png
│   │   ├── genemania-export.png
│   │   ├── grid-layout.png
│   │   ├── images-breadthfirst-layout.png
│   │   ├── initialisation.png
│   │   ├── klay-layout.png
│   │   ├── labels.png
│   │   ├── linkout-example.png
│   │   ├── multiple-instances.png
│   │   ├── performance-tuning.png
│   │   ├── pie-style.png
│   │   ├── popper-tippy.png
│   │   ├── popper.png
│   │   ├── qtip-extension.png
│   │   ├── spread-layout.png
│   │   ├── tokyo-railways.png
│   │   ├── visual-style.png
│   │   └── wine-cheese-map.png
│   ├── index.html
│   ├── js
│   │   ├── cytoscape.min.js
│   │   └── script.js
│   ├── md
│   │   ├── animation
│   │   │   ├── apply.md
│   │   │   ├── pause.md
│   │   │   ├── play.md
│   │   │   ├── progress.md
│   │   │   ├── promise.md
│   │   │   ├── reverse.md
│   │   │   └── stop.md
│   │   ├── animations.md
│   │   ├── architecture.md
│   │   ├── collection
│   │   │   ├── aStar.md
│   │   │   ├── absoluteComplement.md
│   │   │   ├── addClass.md
│   │   │   ├── affinityPropagation.md
│   │   │   ├── algorithms.md
│   │   │   ├── allAre.md
│   │   │   ├── allAreNeighbors.md
│   │   │   ├── animate.md
│   │   │   ├── anySame.md
│   │   │   ├── bellmanFord.md
│   │   │   ├── betweennessCentrality.md
│   │   │   ├── boundingBox.md
│   │   │   ├── breadthFirstSearch.md
│   │   │   ├── classes.md
│   │   │   ├── closenessCentrality.md
│   │   │   ├── closenessCentralityNormalized.md
│   │   │   ├── codirectedEdges.md
│   │   │   ├── collection.md
│   │   │   ├── commonAncestors.md
│   │   │   ├── compoundNodes.md
│   │   │   ├── connectedEdges.md
│   │   │   ├── connectedNodes.md
│   │   │   ├── contains.md
│   │   │   ├── controlPoints.md
│   │   │   ├── data.md
│   │   │   ├── degree.md
│   │   │   ├── degreeCentrality.md
│   │   │   ├── degreeCentralityNormalized.md
│   │   │   ├── delay.md
│   │   │   ├── depthFirstSearch.md
│   │   │   ├── diff.md
│   │   │   ├── difference.md
│   │   │   ├── dijkstra.md
│   │   │   ├── edgesTo.md
│   │   │   ├── edgesWith.md
│   │   │   ├── emit.md
│   │   │   ├── eq.md
│   │   │   ├── every.md
│   │   │   ├── filter.md
│   │   │   ├── flashClass.md
│   │   │   ├── floydWarshall.md
│   │   │   ├── forEach.md
│   │   │   ├── fuzzyCMeans.md
│   │   │   ├── grabify.md
│   │   │   ├── group.md
│   │   │   ├── hasClass.md
│   │   │   ├── hierarchicalClustering.md
│   │   │   ├── incomers.md
│   │   │   ├── intersection.md
│   │   │   ├── is.md
│   │   │   ├── json.md
│   │   │   ├── jsons.md
│   │   │   ├── kMeans.md
│   │   │   ├── kMedoids.md
│   │   │   ├── kargerStein.md
│   │   │   ├── kruskal.md
│   │   │   ├── layout.md
│   │   │   ├── layoutDimensions.md
│   │   │   ├── layoutPositions.md
│   │   │   ├── lock.md
│   │   │   ├── map.md
│   │   │   ├── markovClustering.md
│   │   │   ├── max.md
│   │   │   ├── merge.md
│   │   │   ├── midpoint.md
│   │   │   ├── min.md
│   │   │   ├── move.md
│   │   │   ├── neighborhood.md
│   │   │   ├── numericStyle.md
│   │   │   ├── numericStyleUnits.md
│   │   │   ├── on.md
│   │   │   ├── once.md
│   │   │   ├── one.md
│   │   │   ├── outgoers.md
│   │   │   ├── pageRank.md
│   │   │   ├── parallelEdges.md
│   │   │   ├── position.md
│   │   │   ├── positions.md
│   │   │   ├── predecessors.md
│   │   │   ├── promiseOn.md
│   │   │   ├── reduce.md
│   │   │   ├── remove.md
│   │   │   ├── removeClass.md
│   │   │   ├── removeCss.md
│   │   │   ├── removeData.md
│   │   │   ├── removeListener.md
│   │   │   ├── renderedCss.md
│   │   │   ├── restore.md
│   │   │   ├── same.md
│   │   │   ├── scratch.md
│   │   │   ├── segmentPoints.md
│   │   │   ├── select.md
│   │   │   ├── selectify.md
│   │   │   ├── size.md
│   │   │   ├── some.md
│   │   │   ├── sort.md
│   │   │   ├── source.md
│   │   │   ├── sources.md
│   │   │   ├── stop.md
│   │   │   ├── style.md
│   │   │   ├── successors.md
│   │   │   ├── symmetricDifference.md
│   │   │   ├── target.md
│   │   │   ├── targets.md
│   │   │   ├── toggleClass.md
│   │   │   ├── ungrabify.md
│   │   │   ├── union.md
│   │   │   ├── unlock.md
│   │   │   ├── unmerge.md
│   │   │   ├── unselect.md
│   │   │   └── unselectify.md
│   │   ├── core
│   │   │   ├── add.md
│   │   │   ├── animate.md
│   │   │   ├── autolock.md
│   │   │   ├── autoungrabify.md
│   │   │   ├── autounselectify.md
│   │   │   ├── batch.md
│   │   │   ├── boxSelectionEnabled.md
│   │   │   ├── center.md
│   │   │   ├── collection.md
│   │   │   ├── core.md
│   │   │   ├── delay.md
│   │   │   ├── destroy.md
│   │   │   ├── elements.md
│   │   │   ├── emit.md
│   │   │   ├── extent.md
│   │   │   ├── fit.md
│   │   │   ├── forceRender.md
│   │   │   ├── getElementById.md
│   │   │   ├── init.md
│   │   │   ├── jpg.md
│   │   │   ├── json.md
│   │   │   ├── layout.md
│   │   │   ├── load.md
│   │   │   ├── mount.md
│   │   │   ├── notation.md
│   │   │   ├── offRender.md
│   │   │   ├── on.md
│   │   │   ├── onRender.md
│   │   │   ├── one.md
│   │   │   ├── pan.md
│   │   │   ├── panBy.md
│   │   │   ├── panningEnabled.md
│   │   │   ├── png.md
│   │   │   ├── promiseOn.md
│   │   │   ├── remove.md
│   │   │   ├── removeListener.md
│   │   │   ├── reset.md
│   │   │   ├── resize.md
│   │   │   ├── stop.md
│   │   │   ├── style.md
│   │   │   ├── unmount.md
│   │   │   ├── userPanningEnabled.md
│   │   │   ├── userZoomingEnabled.md
│   │   │   ├── viewport.md
│   │   │   ├── zoom.md
│   │   │   └── zoomingEnabled.md
│   │   ├── demos.md
│   │   ├── downloads.md
│   │   ├── events.md
│   │   ├── extensions.md
│   │   ├── getting-started.md
│   │   ├── intro.md
│   │   ├── layout
│   │   │   ├── emit.md
│   │   │   ├── events.md
│   │   │   ├── intro.md
│   │   │   ├── manipulation.md
│   │   │   ├── on.md
│   │   │   ├── one.md
│   │   │   ├── promiseOn.md
│   │   │   ├── removeListener.md
│   │   │   ├── run.md
│   │   │   └── stop.md
│   │   ├── layouts
│   │   │   ├── breadthfirst.md
│   │   │   ├── circle.md
│   │   │   ├── concentric.md
│   │   │   ├── cose.md
│   │   │   ├── grid.md
│   │   │   ├── null.md
│   │   │   ├── preset.md
│   │   │   └── random.md
│   │   ├── links.md
│   │   ├── notation.md
│   │   ├── performance.md
│   │   ├── selectors.md
│   │   └── style.md
│   └── template.html
├── package-lock.json
├── package.json
├── rollup.config.js
├── snippets
│   ├── animated-bfs.js
│   ├── data
│   │   └── performance-tuning.json
│   ├── images.js
│   ├── performance-tuning.js
│   └── visual.js
├── src
│   ├── animation.js
│   ├── cjs.js
│   ├── collection
│   │   ├── algorithms
│   │   │   ├── a-star.js
│   │   │   ├── affinity-propagation.js
│   │   │   ├── bellman-ford.js
│   │   │   ├── betweenness-centrality.js
│   │   │   ├── bfs-dfs.js
│   │   │   ├── closeness-centrality.js
│   │   │   ├── clustering-distances.js
│   │   │   ├── degree-centrality.js
│   │   │   ├── dijkstra.js
│   │   │   ├── floyd-warshall.js
│   │   │   ├── hierarchical-clustering.js
│   │   │   ├── index.js
│   │   │   ├── k-clustering.js
│   │   │   ├── karger-stein.js
│   │   │   ├── kruskal.js
│   │   │   ├── markov-clustering.js
│   │   │   └── page-rank.js
│   │   ├── animation.js
│   │   ├── cache-traversal-call.js
│   │   ├── class.js
│   │   ├── comparators.js
│   │   ├── compounds.js
│   │   ├── data.js
│   │   ├── degree.js
│   │   ├── dimensions
│   │   │   ├── bounds.js
│   │   │   ├── edge-points.js
│   │   │   ├── index.js
│   │   │   ├── position.js
│   │   │   └── width-height.js
│   │   ├── element.js
│   │   ├── events.js
│   │   ├── filter.js
│   │   ├── group.js
│   │   ├── index.js
│   │   ├── iteration.js
│   │   ├── layout.js
│   │   ├── style.js
│   │   ├── switch-functions.js
│   │   ├── traversing.js
│   │   └── zsort.js
│   ├── core
│   │   ├── add-remove.js
│   │   ├── animation
│   │   │   ├── cubic-bezier.js
│   │   │   ├── ease.js
│   │   │   ├── easings.js
│   │   │   ├── index.js
│   │   │   ├── spring.js
│   │   │   ├── start.js
│   │   │   ├── step-all.js
│   │   │   └── step.js
│   │   ├── events.js
│   │   ├── export.js
│   │   ├── index.js
│   │   ├── layout.js
│   │   ├── notification.js
│   │   ├── renderer.js
│   │   ├── search.js
│   │   ├── style.js
│   │   └── viewport.js
│   ├── define
│   │   ├── animation.js
│   │   ├── data.js
│   │   ├── events.js
│   │   └── index.js
│   ├── emitter.js
│   ├── event.js
│   ├── extension.js
│   ├── extensions
│   │   ├── index.js
│   │   ├── layout
│   │   │   ├── breadthfirst.js
│   │   │   ├── circle.js
│   │   │   ├── concentric.js
│   │   │   ├── cose.js
│   │   │   ├── grid.js
│   │   │   ├── index.js
│   │   │   ├── null.js
│   │   │   ├── preset.js
│   │   │   └── random.js
│   │   └── renderer
│   │   ├── base
│   │   │   ├── arrow-shapes.js
│   │   │   ├── coord-ele-math
│   │   │   │   ├── coords.js
│   │   │   │   ├── edge-arrows.js
│   │   │   │   ├── edge-control-points.js
│   │   │   │   ├── edge-endpoints.js
│   │   │   │   ├── edge-projection.js
│   │   │   │   ├── index.js
│   │   │   │   ├── labels.js
│   │   │   │   ├── nodes.js
│   │   │   │   ├── rendered-style.js
│   │   │   │   └── z-ordering.js
│   │   │   ├── images.js
│   │   │   ├── index.js
│   │   │   ├── load-listeners.js
│   │   │   ├── node-shapes.js
│   │   │   └── redraw.js
│   │   ├── canvas
│   │   │   ├── arrow-shapes.js
│   │   │   ├── drawing-edges.js
│   │   │   ├── drawing-elements.js
│   │   │   ├── drawing-images.js
│   │   │   ├── drawing-label-text.js
│   │   │   ├── drawing-nodes.js
│   │   │   ├── drawing-redraw.js
│   │   │   ├── drawing-shapes.js
│   │   │   ├── ele-texture-cache-lookup.js
│   │   │   ├── ele-texture-cache.js
│   │   │   ├── export-image.js
│   │   │   ├── index.js
│   │   │   ├── layered-texture-cache.js
│   │   │   ├── node-shapes.js
│   │   │   └── texture-cache-defs.js
│   │   ├── index.js
│   │   └── null
│   │   └── index.js
│   ├── heap.js
│   ├── index.js
│   ├── is.js
│   ├── map.js
│   ├── math.js
│   ├── promise.js
│   ├── selector
│   │   ├── data.js
│   │   ├── expressions.js
│   │   ├── index.js
│   │   ├── matching.js
│   │   ├── new-query.js
│   │   ├── parse.js
│   │   ├── query-type-match.js
│   │   ├── state.js
│   │   ├── tokens.js
│   │   └── type.js
│   ├── set.js
│   ├── style
│   │   ├── apply.js
│   │   ├── bypass.js
│   │   ├── container.js
│   │   ├── get-for-ele.js
│   │   ├── index.js
│   │   ├── json.js
│   │   ├── parse.js
│   │   ├── properties.js
│   │   └── string-sheet.js
│   ├── stylesheet.js
│   ├── test.js
│   ├── util
│   │   ├── colors.js
│   │   ├── extend.js
│   │   ├── hash.js
│   │   ├── index.js
│   │   ├── maps.js
│   │   ├── memoize.js
│   │   ├── regex.js
│   │   ├── sort.js
│   │   ├── strings.js
│   │   └── timing.js
│   ├── version.js
│   └── window.js
└── test
├── collection-affinity-propagation.js
├── collection-algorithms.js
├── collection-astar.js
├── collection-building-and-filtering.js
├── collection-comparison.js
├── collection-compound-nodes.js
├── collection-data.js
├── collection-fuzzy-c-means.js
├── collection-graph-manipulation.js
├── collection-hierarchical.js
├── collection-iteration.js
├── collection-k-means.js
├── collection-k-medoids.js
├── collection-markov-clustering.js
├── collection-metadata.js
├── collection-position-and-dimensions.js
├── collection-selection.js
├── collection-style.js
├── collection-traversing.js
├── core-export.js
├── core-graph-manipulation.js
├── core-init.js
├── events.js
├── extensions.js
├── index.html
├── lib
│   ├── bluebird.js
│   ├── chai.js
│   ├── expect.js
│   ├── mocha.css
│   └── mocha.js
├── modules
│   ├── emitter.js
│   └── util.js
├── requires
│   └── foo.js
└── selectors.js



Flask用のディレクトリを作る

次に、Flask用のflask_cyディレクトリを作り、その下にtemplatesディレクトリとstaticディレクトリを作ります。



  • templatesディレクトリはHTMLファイルを置く場所


  • staticディレクトリはCSSファイルとJavaScriptファイルを置く場所

$ mkdir flask_cy

$ cd flask_cy
$ mkdir templates
$ mkdir static
$ mkdir static/css

staticディレクトリの下に、git cloneでダウンロードしていたcytoscape.jsフォルダをまるっと移動します。(ドラッグ&ドロップ等)

よく考えたらstaticディレクトリでgit cloneすればよかったorz


Python、HTML、CSS、JavaScriptのコードを作成

今回はJavaScriptのコードはHTMLに入れ込むことにしたので、以下の3つのファイルを作成しました。


  • cy_app.py

  • cy_temp2.html (HTML+JS)

  • style.css


1. Pythonコード


cy_app.py

import json

from flask import Flask, render_template
import sys

json_file = str(sys.argv[1])

app = Flask(__name__)

@app.route("/")
def cy():
with open(json_file , 'r') as f:
elements = json.load(f)

#elemという名前でcy_temp2.htmlにjsonデータを渡す
return render_template("cy_temp2.html",elem=elements)

if __name__ == "__main__":
app.run(debug=True)


nodeとedgeの情報のみが含まれるjsonファイルを、pythonコードの第2引数として与えることを想定したソースコードです。


2. HTML+JS & CSSコード

これらのコードは以下のデモのソースコードを参考に作成しました。

元にしたデモはコチラ

ライセンスページはコチラ

HTMLとCSSの詳細はコチラ


cy_temp2.html

<!DOCTYPE html>

<html>
<head>
<meta name="description" content="[Cytoscape]" />
<link href="/static/css/style.css" rel="stylesheet" />
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<title>Cytoscape result</title>
<script src="/static/cytoscape.js/documentation/js/cytoscape.min.js"></script>
</head>
<body>
<div id="cy"></div>
<script type="text/javascript">
var cy = cytoscape({
container: document.querySelector('#cy'),

boxSelectionEnabled: false,
autounselectify: true,

style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(name)',
'text-valign': 'center',
'color': 'white',
'text-outline-width': 2,
'background-color': '#000080',
'text-outline-color': '#000080'
})
.selector('edge')
.css({
'curve-style': 'bezier',
'line-color': '#8b0000',
'width': 1
})
.selector(':selected')
.css({
'background-color': 'black',
'line-color': 'black',
'target-arrow-color': 'black',
'source-arrow-color': 'black'
})
.selector('.faded')
.css({
'opacity': 0.25,
'text-opacity': 0
}),

elements: {{ elem|tojson }}, //ここに読み込んだjsonデータを流し込む

layout: {
name: 'cose'
}
});

cy.on('tap', 'node', function(e){
var node = e.cyTarget;
var neighborhood = node.neighborhood().add(node);

cy.elements().addClass('faded');
neighborhood.removeClass('faded');
});

cy.on('tap', function(e){
if( e.cyTarget === cy ){
cy.elements().removeClass('faded');
}
});
</script>
</body>
</html>



style.css

@charset 'utf-8';

body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}

#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}


Cytoscape.jsのレイアウトの参照ページ


HTMLファイルで重要なのは中程にあるelements: {{ elem|tojson }}の部分です。これにより、Flaskから受け取ったデータをjson形式で置くことができます。


Pythonを実行してブラウザで表示

ターミナルのflask_cyディレクトリで以下のコードを実行します。

$ python cy_app.py yeastelem.json

* Serving Flask app "cy_app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.X:5000/ (Press CTRL+C to quit)

jsonファイルはcyREST-Pythonに付属のyeast.jsonファイルのelements部分のみを取り出したものを使用しました。

cyRESTのウェブサイト

cyRESTのGitHub

これでウェブブラウザのURL欄にhttp://127.0.0.X:5000/を入力すると、ネットワーク図が表示されます。

20181003_cytoscape_qiita.gif

画面キャプチャしながら動かしているのでややカクカクしていますが、何もしないで動かしたときはかなりスムーズに動いて良い感じでした。


他に参考にしたページ

軽量WebフレームワークのFlaskに入門

Flaskの簡単な使い方

Cytoscape.jsを試してみた