├── d3heatmap ├── d3js │ ├── __init__.py │ ├── d3.v4.js │ ├── d3.v2.min.js │ ├── d3script.html │ ├── d3.scale.chromatic.v1.min.js │ └── d3heatmap.html ├── __init__.py ├── examples.py └── d3heatmap.py ├── docs ├── example │ ├── __init__.py │ ├── d3.v2.min.js │ ├── d3heatmap.html │ └── data.json └── figs │ ├── example_1.png │ ├── example_2.png │ ├── example_3.png │ ├── example_4.png │ ├── example_5.png │ └── example_6.png ├── requirements-dev.txt ├── tests └── test_d3heatmap.py ├── MANIFEST.in ├── requirements.txt ├── make_clean.sh ├── CITATION.cff ├── make_sphinx_and_commit.sh ├── .github └── FUNDING.yml ├── LICENSE ├── setup.py ├── .gitignore ├── notebooks └── d3heatmap.ipynb └── README.md /d3heatmap/d3js/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/example/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | sphinx_rtd_theme 2 | rst2pdf 3 | pip install spyder-kernels 4 | -------------------------------------------------------------------------------- /tests/test_d3heatmap.py: -------------------------------------------------------------------------------- 1 | import d3heatmap as d3heatmap 2 | 3 | def test_plot(): 4 | pass -------------------------------------------------------------------------------- /d3heatmap/d3js/d3.v4.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/d3heatmap/d3js/d3.v4.js -------------------------------------------------------------------------------- /docs/figs/example_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/figs/example_1.png -------------------------------------------------------------------------------- /docs/figs/example_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/figs/example_2.png -------------------------------------------------------------------------------- /docs/figs/example_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/figs/example_3.png -------------------------------------------------------------------------------- /docs/figs/example_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/figs/example_4.png -------------------------------------------------------------------------------- /docs/figs/example_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/figs/example_5.png -------------------------------------------------------------------------------- /docs/figs/example_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/figs/example_6.png -------------------------------------------------------------------------------- /d3heatmap/d3js/d3.v2.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/d3heatmap/d3js/d3.v2.min.js -------------------------------------------------------------------------------- /docs/example/d3.v2.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/example/d3.v2.min.js -------------------------------------------------------------------------------- /docs/example/d3heatmap.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erdogant/d3heatmap/HEAD/docs/example/d3heatmap.html -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include d3heatmap/d3js/*.js 2 | include d3heatmap/d3js/*.css 3 | include d3heatmap/d3js/*.html 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | #conda create -n env_d3heatmap python=3.6 2 | #conda activate env_d3heatmap 3 | #conda install spyder 4 | 5 | wget 6 | matplotlib 7 | numpy 8 | pandas 9 | tqdm 10 | -------------------------------------------------------------------------------- /make_clean.sh: -------------------------------------------------------------------------------- 1 | echo "Cleaning previous builds first.." 2 | rm -rf dist 3 | rm -rf build 4 | rm -rf d3heatmap.egg-info 5 | rm -rf __pycache__ 6 | rm -rf d3heatmap/__pycache__ 7 | rm -rf d3heatmap/utils/__pycache__ 8 | rm -rf .pytest_cache 9 | rm -rf .pylint.d 10 | rm -rf d3heatmap/data/*.zip 11 | rm -rf d3heatmap/data/*.csv 12 | rm -rf *.js 13 | rm -rf *.html 14 | rm -rf *.css 15 | rm -rf *.dot 16 | rm -rf *.png 17 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | # YAML 1.2 2 | --- 3 | authors: 4 | - 5 | family-names: Taskesen 6 | given-names: Erdogan 7 | orcid: "https://orcid.org/0000-0002-3430-9618" 8 | cff-version: "1.1.0" 9 | date-released: 2019-12-28 10 | keywords: 11 | - "heatmap" 12 | - "interactive" 13 | - "clustering" 14 | - "d3js" 15 | - "python" 16 | license: "MIT" 17 | message: "If you use this software, please cite it using these metadata." 18 | repository-code: "https://github.com/erdogant/d3heatmap" 19 | title: "Interactive and standalone heatmaps (d3heatmap)" 20 | version: "0.1.7" 21 | ... 22 | -------------------------------------------------------------------------------- /make_sphinx_and_commit.sh: -------------------------------------------------------------------------------- 1 | echo "$PWD" 2 | cd docs 3 | echo "$PWD" 4 | 5 | echo "Cleaning previous builds first.." 6 | make.bat clean 7 | 8 | echo "Building new html.." 9 | make.bat html 10 | 11 | cd .. 12 | 13 | echo "Press [q]uit to Quit and [Enter] key to: git add -> commit -> push." 14 | read VAR 15 | 16 | 17 | if [[ $VAR = "" ]]; then 18 | read -p "Ready?" 19 | git pull 20 | git add . 21 | git commit -m "update sphinx pages" 22 | git push 23 | 24 | read -p "All done! Press [Enter] to close this window." 25 | exit 26 | fi 27 | 28 | 29 | if [ $VAR == "q" ]; then 30 | echo Quit! 31 | fi 32 | 33 | read -p "Press [Enter] to close this window." 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [erdogant] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Erdogan Taskesen 4 | d3heatmap - Python package 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /d3heatmap/__init__.py: -------------------------------------------------------------------------------- 1 | from d3heatmap import d3heatmap 2 | 3 | 4 | __author__ = 'Erdogan Tasksen' 5 | __email__ = 'erdogant@gmail.com' 6 | __version__ = '0.2.3' 7 | 8 | # module level doc-string 9 | __doc__ = """ 10 | d3heatmap 11 | ===================================================================== 12 | 13 | Description 14 | ----------- 15 | d3heatmap is a Python package to create interactive heatmaps based on d3js. 16 | 17 | Example 18 | ------- 19 | >>> # Load library 20 | >>> from d3heatmap import d3heatmap as d3 21 | >>> 22 | >>> # Example 1: 23 | >>> df = d3.import_example() 24 | >>> # Create heatmap 25 | >>> paths = d3.heatmap(df, vmax=1) 26 | >>> 27 | >>> # Example 2: 28 | >>> df = d3.import_example(size=(12,20)) 29 | >>> # Create heatmap 30 | >>> paths = d3.matrix(df) 31 | >>> 32 | >>> # Example 3: 33 | >>> # The dataframe contains more columns then rows. Adjust the size and color differently. 34 | >>> paths = d3.matrix(df, fontsize=10, title='Hooray!', description='d3 matrix is created using https://github.com/erdogant/d3heatmap.', path='c:/temp/example/d3_matrix.html', width=600, height=300, cmap='interpolateGreens', vmin=1) 35 | >>> 36 | 37 | References 38 | ---------- 39 | * https://github.com/erdogant/d3heatmap 40 | * https://d3-graph-gallery.com 41 | * https://https://d3js.org/ 42 | """ 43 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | import re 3 | 4 | # versioning ------------ 5 | VERSIONFILE="d3heatmap/__init__.py" 6 | getversion = re.search( r"^__version__ = ['\"]([^'\"]*)['\"]", open(VERSIONFILE, "rt").read(), re.M) 7 | if getversion: 8 | new_version = getversion.group(1) 9 | else: 10 | raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,)) 11 | 12 | # Setup ------------ 13 | with open("README.md", "r") as fh: 14 | long_description = fh.read() 15 | setuptools.setup( 16 | install_requires=['ismember','clusteval', 'numpy', 'pandas'], 17 | python_requires='>=3', 18 | name='d3heatmap', 19 | version=new_version, 20 | author="Erdogan Taskesen", 21 | author_email="erdogant@gmail.com", 22 | description="Python package to create interactive heatmap based on d3js.", 23 | long_description=long_description, 24 | long_description_content_type="text/markdown", 25 | url="https://github.com/erdogant/d3heatmap", 26 | download_url = 'https://github.com/erdogant/d3heatmap/archive/' + new_version+'.tar.gz', 27 | packages=setuptools.find_packages(), # Searches throughout all dirs for files to include 28 | include_package_data=True, # Must be true to include files depicted in MANIFEST.in 29 | license_files=["LICENSE"], 30 | classifiers=[ 31 | "Programming Language :: Python :: 3", 32 | "License :: OSI Approved :: MIT License", 33 | "Operating System :: OS Independent", 34 | ], 35 | ) 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | d3heatmap/data/ 10 | 11 | # Distribution / packaging 12 | .pylint.* 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | pip-wheel-metadata/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | .pylint.* -------------------------------------------------------------------------------- /notebooks/d3heatmap.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "d3heatmap.ipynb", 7 | "provenance": [] 8 | }, 9 | "kernelspec": { 10 | "name": "python3", 11 | "display_name": "Python 3" 12 | } 13 | }, 14 | "cells": [ 15 | { 16 | "cell_type": "markdown", 17 | "metadata": { 18 | "id": "bn1shPtj5B1K" 19 | }, 20 | "source": [ 21 | "**d3heatmap** is a Python package to create *interactive heatmaps* based on d3js. \n", 22 | "\n", 23 | "The **aim** of d3heatmap is to create interactive heatmaps that can be used stand-alone and visual attractive. This library does **not** require you any additional installation, downloads or setting paths to your systems environments. You just need python and this library. All other is taken care off. There are two main functions to create a heatmap matrix and heatmap and there are some differences between the two.\n", 24 | "\n", 25 | "More information can be found here:\n", 26 | "\n", 27 | "* [Github](https://github.com/erdogant/d3heatmap)\n", 28 | "\n" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "metadata": { 34 | "id": "bLW2rBTm5A_Y" 35 | }, 36 | "source": [ 37 | "!pip install -U d3heatmap" 38 | ], 39 | "execution_count": null, 40 | "outputs": [] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "metadata": { 45 | "id": "rsF9wTuj6yEV" 46 | }, 47 | "source": [ 48 | "import d3heatmap\n", 49 | "print(d3heatmap.__version__)" 50 | ], 51 | "execution_count": null, 52 | "outputs": [] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "metadata": { 57 | "id": "-b-D9mmG5y9v" 58 | }, 59 | "source": [ 60 | "# Load library\n", 61 | "from d3heatmap import d3heatmap as d3" 62 | ], 63 | "execution_count": null, 64 | "outputs": [] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "metadata": { 69 | "id": "lNB2xz-t5oyP" 70 | }, 71 | "source": [ 72 | "# Load some random data\n", 73 | "df = d3.import_example()" 74 | ], 75 | "execution_count": null, 76 | "outputs": [] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "metadata": { 81 | "id": "8ppPQe235vpj" 82 | }, 83 | "source": [ 84 | "# Create heatmap. Note that this is not allowed on colab as it requires to write the html file to disk.\n", 85 | "paths = results = d3.heatmap(df, showfig=False)" 86 | ], 87 | "execution_count": null, 88 | "outputs": [] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "metadata": { 93 | "id": "ofV4mvHU63pd" 94 | }, 95 | "source": [ 96 | "" 97 | ], 98 | "execution_count": null, 99 | "outputs": [] 100 | } 101 | ] 102 | } -------------------------------------------------------------------------------- /d3heatmap/examples.py: -------------------------------------------------------------------------------- 1 | # %% 2 | # import d3heatmap as d3 3 | # print(dir(d3)) 4 | # print(d3.__version__) 5 | 6 | # %% 7 | import pandas as pd 8 | import numpy as np 9 | from d3heatmap import d3heatmap as d3 10 | 11 | # %% 12 | # Import example 13 | df = d3.import_example() 14 | # Create interactive heatmap 15 | results = d3.heatmap(df, vmax=1, path='c:/temp/d3_matrix.html', color=None) 16 | 17 | 18 | # %% Create heatmap without clustering 19 | df = d3.import_example(size=(6, 20)) 20 | 21 | # Create matrix using default settings 22 | # d3.matrix(df) 23 | 24 | # The dataframe contains more columns then rows. Adjust the size and color differently. 25 | d3.matrix(df, fontsize=10, title='Hooray!', description='d3 matrix is created using https://github.com/erdogant/d3heatmap.', path='c:/temp/d3_matrix.html', width=600, height=300, cmap='interpolateGreens', vmin=1, showfig=True) 26 | 27 | 28 | # %% Create heatmap with clustering 29 | 30 | # Import example 31 | df = d3.import_example() 32 | 33 | # Create interactive heatmap 34 | results = d3.heatmap(df, vmax=1, path='c:/temp/d3_matrix.html', color=None) 35 | 36 | # Create heatmap with some user-defined settings 37 | # results = d3.heatmap(df, vmax=1, width=800, height=800, path='c:/temp/example/d3_heatmap.html', title='Created in d3heatmap', description='d3 heatmap is created using https://github.com/erdogant/d3heatmap. This heatmap is a stand-alone application!') 38 | 39 | 40 | # %% Plot same adjacency matrix using heatmap and matrix 41 | df = d3.import_example() 42 | results = d3.heatmap(df, vmax=1, title='d3heatmap with the heatmap function.') 43 | results = d3.matrix(df, title='d3heatmap with the matrix function.', cmap='interpolateGreens', path='c:/temp/matrix.html') 44 | 45 | # %% Several examples 46 | df = pd.DataFrame(np.random.randint(0, 10, size=(7, 52))) 47 | 48 | d3.matrix(df, fontsize=10, title='Hooray!', description='Heatmap in d3js using python!', path='d3heatmap_example_1.html', height=200, width=750, cmap='interpolateGreens') 49 | 50 | # Change min-max range 51 | d3.matrix(df, fontsize=10, title='Hooray!', description='Heatmap in d3js using python!', path='d3heatmap_example_2.html', height=200, width=750, cmap='interpolateGreens', vmin=8, vmax=10) 52 | 53 | # Scaling 54 | d3.matrix(df, fontsize=10, title='Hooray!', description='Heatmap in d3js using python!', path='d3heatmap_example_3.html', height=200, width=750, cmap='interpolateGreens', scale=True, vmin=80, vmax=100) 55 | 56 | # Change colormap 57 | d3.matrix(df, fontsize=10, title='Hooray!', description='Heatmap in d3js using python!', path='d3heatmap_example_4.html', height=200, width=750, cmap='interpolateGreens', scale=True) 58 | 59 | # Set defaults 60 | d3.matrix(df, fontsize=10, title='Hooray!', description='Heatmap in d3js using python!', path='d3heatmap_example_5.html', height=200, width=750, cmap='interpolateGreens', scale=False, vmin=None, vmax=None) 61 | 62 | # Change stroke color 63 | d3.matrix(df, fontsize=10, title='Hooray!', description='Heatmap in d3js using python!', path='d3heatmap_example_6.html', height=200, width=750, cmap='interpolateGreens', scale=False, stroke='black') 64 | 65 | # Change several parameters 66 | d3.matrix(df, fontsize=10, title='D3Heatmap', description='Heatmap in d3js using python!', path='d3heatmap_example_7.html', height=200, width=750, cmap='interpolateGreens', scale=False, stroke='red', vmin=None, vmax=None) 67 | 68 | # %% -------------------------------------------------------------------------------- /d3heatmap/d3js/d3script.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## This library is since 18-01-2023 fully implemented in [D3Blocks](https://d3blocks.github.io/d3blocks/pages/html/Heatmap.html). This repo will be froozen at v0.2.3 and not updated anymore. Please use heatmap in D3Blocks for updates and further support. 2 | 3 | # d3heatmap 4 | 5 | [![Project Status](http://www.repostatus.org/badges/latest/moved.svg)](http://www.repostatus.org/#Moved) 6 | [![Python](https://img.shields.io/pypi/pyversions/d3heatmap)](https://img.shields.io/pypi/pyversions/d3heatmap) 7 | [![Pypi](https://img.shields.io/pypi/v/d3heatmap)](https://pypi.org/project/d3heatmap/) 8 | [![Docs](https://img.shields.io/badge/Sphinx-Docs-Green)](https://d3blocks.github.io/d3blocks/pages/html/Heatmap.html) 9 | [![LOC](https://sloc.xyz/github/erdogant/d3heatmap/?category=code)](https://github.com/erdogant/d3heatmap/) 10 | [![Downloads](https://static.pepy.tech/personalized-badge/d3heatmap?period=month&units=international_system&left_color=grey&right_color=brightgreen&left_text=PyPI%20downloads/month)](https://pepy.tech/project/d3heatmap) 11 | [![Downloads](https://static.pepy.tech/personalized-badge/d3heatmap?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads)](https://pepy.tech/project/d3heatmap) 12 | [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/erdogant/d3heatmap/blob/master/LICENSE) 13 | [![Forks](https://img.shields.io/github/forks/erdogant/d3heatmap.svg)](https://github.com/erdogant/d3heatmap/network) 14 | [![Issues](https://img.shields.io/github/issues/erdogant/d3heatmap.svg)](https://github.com/erdogant/d3heatmap/issues) 15 | [![DOI](https://zenodo.org/badge/298880904.svg)](https://zenodo.org/badge/latestdoi/298880904) 16 | [![Medium](https://img.shields.io/badge/Medium-Blog-green)](https://towardsdatascience.com/d3blocks-the-python-library-to-create-interactive-and-standalone-d3js-charts-3dda98ce97d4) 17 | [![Donate](https://img.shields.io/badge/Support%20this%20project-grey.svg?logo=github%20sponsors)](https://d3blocks.github.io/d3blocks/pages/html/Documentation.html) 18 | 19 | 20 | 21 | 22 | ``d3heatmap`` is a Python package to create interactive heatmaps based on d3js. 23 | * The **aim** of d3heatmap is to create interactive heatmaps that can be used stand-alone and being visual attractive. 24 | * This library does not require any additional installation of javascript, or downloads or setting paths to your systems environments. You just need python and pip install this library. There are two main functions to create a heatmap and there are some differences between the two. Read below for more details. Have fun! 25 | 26 | 27 | ``` 28 | pip install d3blocks 29 | 30 | # Import 31 | from d3blocks import D3Blocks 32 | 33 | # Initialize 34 | d3 = D3Blocks() 35 | 36 | # Load example data 37 | df = d3.import_example('stormofswords') 38 | df = d3.vec2adjmat(df['source'], df['target'], weight=df['weight'], symmetric=True) 39 | 40 | # Plot 41 | d3.heatmap(df) 42 | ``` 43 | 44 | 45 | ### Functionalities 46 | 47 | ``d3heatmap.matrix`` 48 | * Allows none symetric adjacency matrices. 49 | * Colormap can be changed. 50 | * No clustering. 51 | * round-ish elements. 52 | 53 | ``d3heatmap.heatmap`` 54 | * Allows Clustering. 55 | * Colormap is fixed. 56 | * Advanced cluster coloring. Clusters are colored and within each cluster the color is incremental based on the value. 57 | * Adjacency matrix must be symetric. 58 | 59 | # 60 | **Star the [D3Blocks](https://d3blocks.github.io/d3blocks/pages/html/Heatmap.html) repo if you like it! ⭐️** 61 | # 62 | 63 | 64 | #### Installation 65 | ``` 66 | pip install d3heatmap 67 | ``` 68 | 69 | * Alternatively, install d3heatmap from the GitHub source: 70 | ```bash 71 | git clone https://github.com/erdogant/d3heatmap.git 72 | cd d3heatmap 73 | pip install -U . 74 | ``` 75 | 76 | #### Import d3heatmap 77 | 78 | ```python 79 | from d3heatmap import d3heatmap as d3 80 | ``` 81 | 82 | #### Example 1: plot using the heatmap function 83 | 84 | ```python 85 | df = d3.import_example() 86 | # Create heatmap 87 | paths = results = d3.heatmap(df) 88 | ``` 89 | 90 | Klik on the figure for the interactive example. 91 |

92 | 93 | 94 | 95 |

96 | 97 | #### Example 2: plot using the matrix function 98 | 99 | ```python 100 | df = d3.import_example(size=(6,20)) 101 | # Create heatmap 102 | paths = d3.matrix(df) 103 | ``` 104 | 105 |

106 | 107 |

108 | 109 | 110 | #### Example 3: plot using the matrix function 111 | 112 | ```python 113 | # The dataframe contains more columns then rows. Adjust the size and color differently. 114 | df = d3.import_example(size=(6,20)) 115 | # Create heatmap 116 | paths = d3.matrix(df, fontsize=10, title='Hooray!', description='d3 matrix is created using https://github.com/erdogant/d3heatmap.', path='c:/temp/example/d3_matrix.html', width=600, height=300, cmap='interpolateGreens', vmin=1) 117 | ``` 118 | 119 |

120 | 121 |

122 | 123 | 124 | #### Example 4: Matrix with parameters changed: 125 | 126 | ```python 127 | # The dataframe contains more columns then rows. Adjust the size and color differently. 128 | df = d3.import_example(size=(6,20)) 129 | # Create heatmap 130 | paths = d3.matrix(df, fontsize=10, title='Hooray!', description='d3 matrix is created using https://github.com/erdogant/d3heatmap.', path='c:/temp/example/d3_matrix.html', width=600, height=300, cmap='interpolateGreens', vmin=1) 131 | ``` 132 | 133 |

134 | 135 |

136 | 137 | 138 | #### Example 4: Comparison heatmap vs matrix: 139 | There are quit some differences between the ``heatmap`` vs ``matrix`` functionality. 140 | 141 | ```python 142 | df = d3.import_example() 143 | results = d3.heatmap(df, title='d3heatmap with the heatmap function.', path='heatmap.html') 144 | results = d3.matrix(df, title='d3heatmap with the matrix function.', cmap='interpolatePRGn', path='matrix.html', width=700, height=700) 145 | ``` 146 | 147 |

148 | 149 | 150 |

151 | 152 | #### Citation 153 | Please cite d3heatmap in your publications if this is useful for your research. See right column for citation information. 154 | 155 | #### References 156 | * https://github.com/erdogant/d3heatmap 157 | * https://d3-graph-gallery.com 158 | * https://https://d3js.org/ 159 | 160 | ### Maintainer 161 | * Erdogan Taskesen, github: [erdogant](https://github.com/erdogant) 162 | * This work is created and maintained in my free time. If you wish to buy me a Coffee for this work, it is very appreciated. 163 | * Contributions are welcome. 164 | * Star it if you like it! 165 | -------------------------------------------------------------------------------- /docs/example/data.json: -------------------------------------------------------------------------------- 1 | {"nodes": 2 | [ 3 | {"name":"Myriel","group":1}, 4 | {"name":"Napoleon","group":1}, 5 | {"name":"Mlle.Baptistine","group":1}, 6 | {"name":"Mme.Magloire","group":1}, 7 | {"name":"CountessdeLo","group":1}, 8 | {"name":"Geborand","group":1}, 9 | {"name":"Champtercier","group":1}, 10 | {"name":"Cravatte","group":1}, 11 | {"name":"Count","group":1}, 12 | {"name":"OldMan","group":1}, 13 | {"name":"Labarre","group":2}, 14 | {"name":"Valjean","group":2}, 15 | {"name":"Marguerite","group":3}, 16 | {"name":"Mme.deR","group":2}, 17 | {"name":"Isabeau","group":2}, 18 | {"name":"Gervais","group":2}, 19 | {"name":"Tholomyes","group":3}, 20 | {"name":"Listolier","group":3}, 21 | {"name":"Fameuil","group":3}, 22 | {"name":"Blacheville","group":3}, 23 | {"name":"Favourite","group":3}, 24 | {"name":"Dahlia","group":3}, 25 | {"name":"Zephine","group":3}, 26 | {"name":"Fantine","group":3}, 27 | {"name":"Mme.Thenardier","group":4}, 28 | {"name":"Thenardier","group":4}, 29 | {"name":"Cosette","group":5}, 30 | {"name":"Javert","group":4}, 31 | {"name":"Fauchelevent","group":0}, 32 | {"name":"Bamatabois","group":2}, 33 | {"name":"Perpetue","group":3}, 34 | {"name":"Simplice","group":2}, 35 | {"name":"Scaufflaire","group":2}, 36 | {"name":"Woman1","group":2}, 37 | {"name":"Judge","group":2}, 38 | {"name":"Champmathieu","group":2}, 39 | {"name":"Brevet","group":2}, 40 | {"name":"Chenildieu","group":2}, 41 | {"name":"Cochepaille","group":2}, 42 | {"name":"Pontmercy","group":4}, 43 | {"name":"Boulatruelle","group":6}, 44 | {"name":"Eponine","group":4}, 45 | {"name":"Anzelma","group":4}, 46 | {"name":"Woman2","group":5}, 47 | {"name":"MotherInnocent","group":0}, 48 | {"name":"Gribier","group":0}, 49 | {"name":"Jondrette","group":7}, 50 | {"name":"Mme.Burgon","group":7}, 51 | {"name":"Gavroche","group":8}, 52 | {"name":"Gillenormand","group":5}, 53 | {"name":"Magnon","group":5}, 54 | {"name":"Mlle.Gillenormand","group":5}, 55 | {"name":"Mme.Pontmercy","group":5}, 56 | {"name":"Mlle.Vaubois","group":5}, 57 | {"name":"Lt.Gillenormand","group":5}, 58 | {"name":"Marius","group":8}, 59 | {"name":"BaronessT","group":5}, 60 | {"name":"Mabeuf","group":8}, 61 | {"name":"Enjolras","group":8}, 62 | {"name":"Combeferre","group":8}, 63 | {"name":"Prouvaire","group":8}, 64 | {"name":"Feuilly","group":8}, 65 | {"name":"Courfeyrac","group":8}, 66 | {"name":"Bahorel","group":8}, 67 | {"name":"Bossuet","group":8}, 68 | {"name":"Joly","group":8}, 69 | {"name":"Grantaire","group":8}, 70 | {"name":"MotherPlutarch","group":9}, 71 | {"name":"Gueulemer","group":4}, 72 | {"name":"Babet","group":4}, 73 | {"name":"Claquesous","group":4}, 74 | {"name":"Montparnasse","group":4}, 75 | {"name":"Toussaint","group":5}, 76 | {"name":"Child1","group":10}, 77 | {"name":"Child2","group":10}, 78 | {"name":"Brujon","group":4}, 79 | {"name":"Mme.Hucheloup","group":8} 80 | ], 81 | "links": 82 | [ 83 | {"source":1,"target":0,"value":1}, 84 | {"source":2,"target":0,"value":8}, 85 | {"source":3,"target":0,"value":10}, 86 | {"source":3,"target":2,"value":6}, 87 | {"source":4,"target":0,"value":1}, 88 | {"source":5,"target":0,"value":1}, 89 | {"source":6,"target":0,"value":1}, 90 | {"source":7,"target":0,"value":1}, 91 | {"source":8,"target":0,"value":2}, 92 | {"source":9,"target":0,"value":1}, 93 | {"source":11,"target":10,"value":1}, 94 | {"source":11,"target":3,"value":3}, 95 | {"source":11,"target":2,"value":3}, 96 | {"source":11,"target":0,"value":5}, 97 | {"source":12,"target":11,"value":1}, 98 | {"source":13,"target":11,"value":1}, 99 | {"source":14,"target":11,"value":1}, 100 | {"source":15,"target":11,"value":1}, 101 | {"source":17,"target":16,"value":4}, 102 | {"source":18,"target":16,"value":4}, 103 | {"source":18,"target":17,"value":4}, 104 | {"source":19,"target":16,"value":4}, 105 | {"source":19,"target":17,"value":4}, 106 | {"source":19,"target":18,"value":4}, 107 | {"source":20,"target":16,"value":3}, 108 | {"source":20,"target":17,"value":3}, 109 | {"source":20,"target":18,"value":3}, 110 | {"source":20,"target":19,"value":4}, 111 | {"source":21,"target":16,"value":3}, 112 | {"source":21,"target":17,"value":3}, 113 | {"source":21,"target":18,"value":3}, 114 | {"source":21,"target":19,"value":3}, 115 | {"source":21,"target":20,"value":5}, 116 | {"source":22,"target":16,"value":3}, 117 | {"source":22,"target":17,"value":3}, 118 | {"source":22,"target":18,"value":3}, 119 | {"source":22,"target":19,"value":3}, 120 | {"source":22,"target":20,"value":4}, 121 | {"source":22,"target":21,"value":4}, 122 | {"source":23,"target":16,"value":3}, 123 | {"source":23,"target":17,"value":3}, 124 | {"source":23,"target":18,"value":3}, 125 | {"source":23,"target":19,"value":3}, 126 | {"source":23,"target":20,"value":4}, 127 | {"source":23,"target":21,"value":4}, 128 | {"source":23,"target":22,"value":4}, 129 | {"source":23,"target":12,"value":2}, 130 | {"source":23,"target":11,"value":9}, 131 | {"source":24,"target":23,"value":2}, 132 | {"source":24,"target":11,"value":7}, 133 | {"source":25,"target":24,"value":13}, 134 | {"source":25,"target":23,"value":1}, 135 | {"source":25,"target":11,"value":12}, 136 | {"source":26,"target":24,"value":4}, 137 | {"source":26,"target":11,"value":31}, 138 | {"source":26,"target":16,"value":1}, 139 | {"source":26,"target":25,"value":1}, 140 | {"source":27,"target":11,"value":17}, 141 | {"source":27,"target":23,"value":5}, 142 | {"source":27,"target":25,"value":5}, 143 | {"source":27,"target":24,"value":1}, 144 | {"source":27,"target":26,"value":1}, 145 | {"source":28,"target":11,"value":8}, 146 | {"source":28,"target":27,"value":1}, 147 | {"source":29,"target":23,"value":1}, 148 | {"source":29,"target":27,"value":1}, 149 | {"source":29,"target":11,"value":2}, 150 | {"source":30,"target":23,"value":1}, 151 | {"source":31,"target":30,"value":2}, 152 | {"source":31,"target":11,"value":3}, 153 | {"source":31,"target":23,"value":2}, 154 | {"source":31,"target":27,"value":1}, 155 | {"source":32,"target":11,"value":1}, 156 | {"source":33,"target":11,"value":2}, 157 | {"source":33,"target":27,"value":1}, 158 | {"source":34,"target":11,"value":3}, 159 | {"source":34,"target":29,"value":2}, 160 | {"source":35,"target":11,"value":3}, 161 | {"source":35,"target":34,"value":3}, 162 | {"source":35,"target":29,"value":2}, 163 | {"source":36,"target":34,"value":2}, 164 | {"source":36,"target":35,"value":2}, 165 | {"source":36,"target":11,"value":2}, 166 | {"source":36,"target":29,"value":1}, 167 | {"source":37,"target":34,"value":2}, 168 | {"source":37,"target":35,"value":2}, 169 | {"source":37,"target":36,"value":2}, 170 | {"source":37,"target":11,"value":2}, 171 | {"source":37,"target":29,"value":1}, 172 | {"source":38,"target":34,"value":2}, 173 | {"source":38,"target":35,"value":2}, 174 | {"source":38,"target":36,"value":2}, 175 | {"source":38,"target":37,"value":2}, 176 | {"source":38,"target":11,"value":2}, 177 | {"source":38,"target":29,"value":1}, 178 | {"source":39,"target":25,"value":1}, 179 | {"source":40,"target":25,"value":1}, 180 | {"source":41,"target":24,"value":2}, 181 | {"source":41,"target":25,"value":3}, 182 | {"source":42,"target":41,"value":2}, 183 | {"source":42,"target":25,"value":2}, 184 | {"source":42,"target":24,"value":1}, 185 | {"source":43,"target":11,"value":3}, 186 | {"source":43,"target":26,"value":1}, 187 | {"source":43,"target":27,"value":1}, 188 | {"source":44,"target":28,"value":3}, 189 | {"source":44,"target":11,"value":1}, 190 | {"source":45,"target":28,"value":2}, 191 | {"source":47,"target":46,"value":1}, 192 | {"source":48,"target":47,"value":2}, 193 | {"source":48,"target":25,"value":1}, 194 | {"source":48,"target":27,"value":1}, 195 | {"source":48,"target":11,"value":1}, 196 | {"source":49,"target":26,"value":3}, 197 | {"source":49,"target":11,"value":2}, 198 | {"source":50,"target":49,"value":1}, 199 | {"source":50,"target":24,"value":1}, 200 | {"source":51,"target":49,"value":9}, 201 | {"source":51,"target":26,"value":2}, 202 | {"source":51,"target":11,"value":2}, 203 | {"source":52,"target":51,"value":1}, 204 | {"source":52,"target":39,"value":1}, 205 | {"source":53,"target":51,"value":1}, 206 | {"source":54,"target":51,"value":2}, 207 | {"source":54,"target":49,"value":1}, 208 | {"source":54,"target":26,"value":1}, 209 | {"source":55,"target":51,"value":6}, 210 | {"source":55,"target":49,"value":12}, 211 | {"source":55,"target":39,"value":1}, 212 | {"source":55,"target":54,"value":1}, 213 | {"source":55,"target":26,"value":21}, 214 | {"source":55,"target":11,"value":19}, 215 | {"source":55,"target":16,"value":1}, 216 | {"source":55,"target":25,"value":2}, 217 | {"source":55,"target":41,"value":5}, 218 | {"source":55,"target":48,"value":4}, 219 | {"source":56,"target":49,"value":1}, 220 | {"source":56,"target":55,"value":1}, 221 | {"source":57,"target":55,"value":1}, 222 | {"source":57,"target":41,"value":1}, 223 | {"source":57,"target":48,"value":1}, 224 | {"source":58,"target":55,"value":7}, 225 | {"source":58,"target":48,"value":7}, 226 | {"source":58,"target":27,"value":6}, 227 | {"source":58,"target":57,"value":1}, 228 | {"source":58,"target":11,"value":4}, 229 | {"source":59,"target":58,"value":15}, 230 | {"source":59,"target":55,"value":5}, 231 | {"source":59,"target":48,"value":6}, 232 | {"source":59,"target":57,"value":2}, 233 | {"source":60,"target":48,"value":1}, 234 | {"source":60,"target":58,"value":4}, 235 | {"source":60,"target":59,"value":2}, 236 | {"source":61,"target":48,"value":2}, 237 | {"source":61,"target":58,"value":6}, 238 | {"source":61,"target":60,"value":2}, 239 | {"source":61,"target":59,"value":5}, 240 | {"source":61,"target":57,"value":1}, 241 | {"source":61,"target":55,"value":1}, 242 | {"source":62,"target":55,"value":9}, 243 | {"source":62,"target":58,"value":17}, 244 | {"source":62,"target":59,"value":13}, 245 | {"source":62,"target":48,"value":7}, 246 | {"source":62,"target":57,"value":2}, 247 | {"source":62,"target":41,"value":1}, 248 | {"source":62,"target":61,"value":6}, 249 | {"source":62,"target":60,"value":3}, 250 | {"source":63,"target":59,"value":5}, 251 | {"source":63,"target":48,"value":5}, 252 | {"source":63,"target":62,"value":6}, 253 | {"source":63,"target":57,"value":2}, 254 | {"source":63,"target":58,"value":4}, 255 | {"source":63,"target":61,"value":3}, 256 | {"source":63,"target":60,"value":2}, 257 | {"source":63,"target":55,"value":1}, 258 | {"source":64,"target":55,"value":5}, 259 | {"source":64,"target":62,"value":12}, 260 | {"source":64,"target":48,"value":5}, 261 | {"source":64,"target":63,"value":4}, 262 | {"source":64,"target":58,"value":10}, 263 | {"source":64,"target":61,"value":6}, 264 | {"source":64,"target":60,"value":2}, 265 | {"source":64,"target":59,"value":9}, 266 | {"source":64,"target":57,"value":1}, 267 | {"source":64,"target":11,"value":1}, 268 | {"source":65,"target":63,"value":5}, 269 | {"source":65,"target":64,"value":7}, 270 | {"source":65,"target":48,"value":3}, 271 | {"source":65,"target":62,"value":5}, 272 | {"source":65,"target":58,"value":5}, 273 | {"source":65,"target":61,"value":5}, 274 | {"source":65,"target":60,"value":2}, 275 | {"source":65,"target":59,"value":5}, 276 | {"source":65,"target":57,"value":1}, 277 | {"source":65,"target":55,"value":2}, 278 | {"source":66,"target":64,"value":3}, 279 | {"source":66,"target":58,"value":3}, 280 | {"source":66,"target":59,"value":1}, 281 | {"source":66,"target":62,"value":2}, 282 | {"source":66,"target":65,"value":2}, 283 | {"source":66,"target":48,"value":1}, 284 | {"source":66,"target":63,"value":1}, 285 | {"source":66,"target":61,"value":1}, 286 | {"source":66,"target":60,"value":1}, 287 | {"source":67,"target":57,"value":3}, 288 | {"source":68,"target":25,"value":5}, 289 | {"source":68,"target":11,"value":1}, 290 | {"source":68,"target":24,"value":1}, 291 | {"source":68,"target":27,"value":1}, 292 | {"source":68,"target":48,"value":1}, 293 | {"source":68,"target":41,"value":1}, 294 | {"source":69,"target":25,"value":6}, 295 | {"source":69,"target":68,"value":6}, 296 | {"source":69,"target":11,"value":1}, 297 | {"source":69,"target":24,"value":1}, 298 | {"source":69,"target":27,"value":2}, 299 | {"source":69,"target":48,"value":1}, 300 | {"source":69,"target":41,"value":1}, 301 | {"source":70,"target":25,"value":4}, 302 | {"source":70,"target":69,"value":4}, 303 | {"source":70,"target":68,"value":4}, 304 | {"source":70,"target":11,"value":1}, 305 | {"source":70,"target":24,"value":1}, 306 | {"source":70,"target":27,"value":1}, 307 | {"source":70,"target":41,"value":1}, 308 | {"source":70,"target":58,"value":1}, 309 | {"source":71,"target":27,"value":1}, 310 | {"source":71,"target":69,"value":2}, 311 | {"source":71,"target":68,"value":2}, 312 | {"source":71,"target":70,"value":2}, 313 | {"source":71,"target":11,"value":1}, 314 | {"source":71,"target":48,"value":1}, 315 | {"source":71,"target":41,"value":1}, 316 | {"source":71,"target":25,"value":1}, 317 | {"source":72,"target":26,"value":2}, 318 | {"source":72,"target":27,"value":1}, 319 | {"source":72,"target":11,"value":1}, 320 | {"source":73,"target":48,"value":2}, 321 | {"source":74,"target":48,"value":2}, 322 | {"source":74,"target":73,"value":3}, 323 | {"source":75,"target":69,"value":3}, 324 | {"source":75,"target":68,"value":3}, 325 | {"source":75,"target":25,"value":3}, 326 | {"source":75,"target":48,"value":1}, 327 | {"source":75,"target":41,"value":1}, 328 | {"source":75,"target":70,"value":1}, 329 | {"source":75,"target":71,"value":1}, 330 | {"source":76,"target":64,"value":1}, 331 | {"source":76,"target":65,"value":1}, 332 | {"source":76,"target":66,"value":1}, 333 | {"source":76,"target":63,"value":1}, 334 | {"source":76,"target":62,"value":1}, 335 | {"source":76,"target":48,"value":1}, 336 | {"source":76,"target":58,"value":1} 337 | ] 338 | } 339 | -------------------------------------------------------------------------------- /d3heatmap/d3js/d3.scale.chromatic.v1.min.js: -------------------------------------------------------------------------------- 1 | // https://d3js.org/d3-scale-chromatic/ v1.5.0 Copyright 2019 Mike Bostock 2 | !function(f,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-interpolate"),require("d3-color")):"function"==typeof define&&define.amd?define(["exports","d3-interpolate","d3-color"],e):e((f=f||self).d3=f.d3||{},f.d3,f.d3)}(this,function(f,e,d){"use strict";function a(f){for(var e=f.length/6|0,d=new Array(e),a=0;a1)&&(f-=Math.floor(f));var e=Math.abs(f-.5);return wf.h=360*f-100,wf.s=1.5-1.5*e,wf.l=.8-.9*e,wf+""},f.interpolateRdBu=x,f.interpolateRdGy=g,f.interpolateRdPu=N,f.interpolateRdYlBu=v,f.interpolateRdYlGn=C,f.interpolateReds=hf,f.interpolateSinebow=function(f){var e;return f=(.5-f)*Math.PI,Af.r=255*(e=Math.sin(f))*e,Af.g=255*(e=Math.sin(f+Pf))*e,Af.b=255*(e=Math.sin(f+Bf))*e,Af+""},f.interpolateSpectral=I,f.interpolateTurbo=function(f){return f=Math.max(0,Math.min(1,f)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+f*(1172.33-f*(10793.56-f*(33300.12-f*(38394.49-14825.05*f)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+f*(557.33+f*(1225.33-f*(3574.96-f*(1073.77+707.56*f)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+f*(3211.1-f*(15327.97-f*(27814-f*(22569.18-6838.66*f)))))))+")"},f.interpolateViridis=xf,f.interpolateWarm=yf,f.interpolateYlGn=Z,f.interpolateYlGnBu=U,f.interpolateYlOrBr=ff,f.interpolateYlOrRd=df,f.schemeAccent=b,f.schemeBlues=af,f.schemeBrBG=u,f.schemeBuGn=L,f.schemeBuPu=q,f.schemeCategory10=c,f.schemeDark2=t,f.schemeGnBu=T,f.schemeGreens=bf,f.schemeGreys=nf,f.schemeOrRd=k,f.schemeOranges=pf,f.schemePRGn=y,f.schemePaired=n,f.schemePastel1=r,f.schemePastel2=o,f.schemePiYG=w,f.schemePuBu=E,f.schemePuBuGn=W,f.schemePuOr=P,f.schemePuRd=H,f.schemePurples=of,f.schemeRdBu=G,f.schemeRdGy=R,f.schemeRdPu=K,f.schemeRdYlBu=Y,f.schemeRdYlGn=O,f.schemeReds=mf,f.schemeSet1=i,f.schemeSet2=l,f.schemeSet3=m,f.schemeSpectral=S,f.schemeTableau10=h,f.schemeYlGn=X,f.schemeYlGnBu=Q,f.schemeYlOrBr=$,f.schemeYlOrRd=ef,Object.defineProperty(f,"__esModule",{value:!0})}); -------------------------------------------------------------------------------- /d3heatmap/d3heatmap.py: -------------------------------------------------------------------------------- 1 | """Heatmap in d3 javascript.""" 2 | # -------------------------------------------------- 3 | # Name : d3heatmap.py 4 | # Author : E.Taskesen 5 | # Contact : erdogant@gmail.com 6 | # github : https://github.com/erdogant/d3heatmap 7 | # Licence : See licences 8 | # -------------------------------------------------- 9 | 10 | from clusteval import clusteval 11 | import numpy as np 12 | import pandas as pd 13 | import webbrowser 14 | import tempfile 15 | from shutil import copyfile 16 | import os 17 | import time 18 | from ismember import ismember 19 | 20 | curpath = os.path.dirname(os.path.abspath(__file__)) 21 | 22 | 23 | # %% 24 | def heatmap(df, color='cluster', path=None, title='d3heatmap', description=None, vmax=None, width=720, height=720, showfig=True, stroke='red', verbose=3): 25 | """Heatmap in d3js. 26 | 27 | Parameters 28 | ---------- 29 | df : pd.DataFrame() 30 | Input data. The index and column names are used for the row/column naming. 31 | color : Numpy array 32 | Should be in the same order as the columns and of the input dataframe 33 | None or 'cluster': a clustering approach is used for coloring. 34 | path : String, (Default: user temp directory) 35 | Directory path to save the output, such as 'c://temp/index.html' 36 | title : String, (default: 'd3 Heatmap!') 37 | Title text. 38 | description : String, (default: 'Heatmap description') 39 | Description text of the heatmap. 40 | vmax : Bool, (default: 100). 41 | Range of colors starting with maximum value. Increasing this value will color the cells more discrete. 42 | * 1 : cells above value >1 are capped. 43 | * None : cells are colored based on the maximum value in the input data. 44 | width : int, (default: 500). 45 | Width of the window. 46 | height : int, (default: 500). 47 | height of the window. 48 | stroke : String, (default: 'red'). 49 | Color of the recangle when hovering over a cell. 50 | * 'red' 51 | * 'black' 52 | showfig : Bool, (default: True) 53 | Open browser with heatmap. 54 | verbose : int [0-5], (default: 3) 55 | Verbosity to print the working-status. The higher the number, the more information. 56 | * 0: None 57 | * 1: Error 58 | * 2: Warning 59 | * 3: Info 60 | * 4: Debug 61 | * 5: Trace 62 | 63 | Example 64 | ------- 65 | >>> # Load library 66 | >>> from d3heatmap import d3heatmap as d3 67 | >>> # Import example 68 | >>> df = d3.import_example() 69 | >>> # Create heatmap 70 | >>> results = d3.heatmap(df, vmax=1) 71 | 72 | Returns 73 | ------- 74 | out : dict. 75 | output path names. 76 | 77 | """ 78 | if len(df.columns.unique())!=len(df.columns): 79 | if verbose>=2: print('[d3heatmap] >Warning: Input data should contain unique column names otherwise d3js randomly removes the non-unique ones.') 80 | if len(df.index.unique())!=len(df.index): 81 | if verbose>=2: print('[d3heatmap] >Warning: Input data should contain unique index names otherwise d3js randomly removes the non-unique ones.') 82 | if description is None: 83 | description = "This heatmap is created in d3js using https://github.com/erdogant/d3heatmap.\n\nA network can be represented by an adjacency matrix, where each cell ij represents an edge from vertex i to vertex j.\n\nGiven this two-dimensional representation of a graph, a natural visualization is to show the matrix! However, the effectiveness of a matrix diagram is heavily dependent on the order of rows and columns: if related nodes are placed closed to each other, it is easier to identify clusters and bridges.\nWhile path-following is harder in a matrix view than in a node-link diagram, matrices have other advantages. As networks get large and highly connected, node-link diagrams often devolve into giant hairballs of line crossings. Line crossings are impossible with matrix views. Matrix cells can also be encoded to show additional data; here color depicts clusters computed by a community-detection algorithm." 84 | if isinstance(color, str) and color=='cluster': 85 | color=None 86 | 87 | # Rescale data 88 | if vmax is not None: 89 | df = _scale(df, vmax=vmax, make_round=False, verbose=verbose) 90 | # if vmin is None: 91 | # vmin = np.min(df.values) 92 | if vmax is None: 93 | vmax = np.max(df.values) 94 | if verbose>=3: print('[d3heatmap] >Set vmax: %.0g.' %(vmax)) 95 | 96 | # Get path to files 97 | d3_library = os.path.abspath(os.path.join(curpath, 'd3js/d3.v2.min.js')) 98 | d3_script = os.path.abspath(os.path.join(curpath, 'd3js/d3heatmap.html')) 99 | 100 | # Check path 101 | filename, dirpath, path = _path_check(path, verbose) 102 | 103 | # Copy files to destination directory 104 | # copyfile(d3_library, os.path.join(dirpath, os.path.basename(d3_library))) 105 | copyfile(d3_script, path) 106 | 107 | # Collect node names 108 | nodes = df.columns.astype(str).values 109 | 110 | # Convert into adj into vector 111 | dfvec = adjmat2vec(df) 112 | uinode, idx = np.unique(nodes, return_index=True) 113 | for node, i in zip(uinode, idx): 114 | dfvec['source'] = dfvec['source'].replace(node, i) 115 | dfvec['target'] = dfvec['target'].replace(node, i) 116 | 117 | # Write to disk (file is not used) 118 | basename, ext = os.path.splitext(filename) 119 | PATHNAME_TO_CSV = os.path.join(dirpath, basename + '.csv') 120 | # dfvec.to_csv(PATHNAME_TO_CSV, index=False) 121 | 122 | # Cluster the nodes 123 | if color is None: 124 | ce = clusteval() 125 | results = ce.fit(df.values) 126 | color = results['labx'] 127 | 128 | # Embed the Data in the HTML. Note that the embedding is an important stap te prevent security issues by the browsers. 129 | # Most (if not all) browser do not accept to read a file using d3.csv or so. It then requires security-by-passes, but thats not the way to go. 130 | # An alternative is use local-host and CORS but then the approach is not user-friendly coz setting up this, is not so straightforward. 131 | # It leaves us by embedding the data in the HTML. Thats what we are going to do here. 132 | 133 | NODE_STR = '\n{\n"nodes":\n[\n' 134 | for i in range(0, len(nodes)): 135 | NODE_STR = NODE_STR + '{"name":' + '"' + nodes[i] + '"' + ',' + '"cluster":' + str(color[i]) + "}," 136 | NODE_STR = NODE_STR + '\n' 137 | NODE_STR = NODE_STR + '],\n' 138 | 139 | EDGE_STR = '"links":\n[\n' 140 | for i in range(0, dfvec.shape[0]): 141 | EDGE_STR = EDGE_STR + '{"source":' + str(dfvec.iloc[i, 0]) + ',' + '"target":' + str(dfvec.iloc[i, 1]) + ',' + '"value":' + str(dfvec.iloc[i, 2]) + '},' 142 | EDGE_STR = EDGE_STR + '\n' 143 | EDGE_STR = EDGE_STR + ']\n}' 144 | 145 | # Final data string 146 | DATA_STR = NODE_STR + EDGE_STR 147 | 148 | # Read the data 149 | # { 150 | # "nodes": 151 | # [ 152 | # {"name":"Name A","cluster":1}, 153 | # {"name":"Name B","cluster":2}, 154 | # {"name":"Name C","cluster":2}, 155 | # {"name":"Name D","cluster":3}, 156 | # ], 157 | # "links": 158 | # [ 159 | # {"source":0,"target":1,"value":1}, 160 | # {"source":2,"target":2,"value":1}, 161 | # {"source":3,"target":1,"value":1}, 162 | # ] 163 | # } 164 | 165 | # Import in the file 166 | with open(path, 'r', encoding="utf8", errors='ignore') as file: d3graphscript = file.read() 167 | 168 | # Read the d3 html with script file 169 | d3graphscript = d3graphscript.replace('$DESCRIPTION$', str(description)) 170 | d3graphscript = d3graphscript.replace('$TITLE$', str(title)) 171 | d3graphscript = d3graphscript.replace('$WIDTH$', str(width)) 172 | d3graphscript = d3graphscript.replace('$WIDTH_DROPDOWN$', str(int(width + 200))) 173 | d3graphscript = d3graphscript.replace('$HEIGHT$', str(height)) 174 | d3graphscript = d3graphscript.replace('$STROKE$', str(stroke)) 175 | d3graphscript = d3graphscript.replace('$DATA_PATH$', filename) 176 | d3graphscript = d3graphscript.replace('$DATA_COMES_HERE$', DATA_STR) 177 | 178 | # Write to file 179 | with open(path, 'w', encoding="utf8", errors='ignore') as file: file.write(d3graphscript) 180 | # Open browser with heatmap 181 | if showfig: webbrowser.open(path, new=1) 182 | 183 | # Return 184 | out = {} 185 | out['filename'] = filename 186 | out['dirpath'] = dirpath 187 | out['path'] = path 188 | out['csv'] = PATHNAME_TO_CSV 189 | return out 190 | 191 | 192 | # %% 193 | def matrix(df, path=None, title='d3heatmap', description='Heatmap description', width=500, height=500, fontsize=10, cmap='interpolateInferno', scale=False, vmin=None, vmax=None, showfig=True, stroke='red', overwrite=True, verbose=3): 194 | """Heatmap in d3 javascript. 195 | 196 | Parameters 197 | ---------- 198 | df : pd.DataFrame() 199 | Input data. The index and column names are used for the row/column naming. 200 | path : String, (Default: user temp directory) 201 | Directory path to save the output, such as 'c://temp/index.html' 202 | title : String, (default: 'd3 Heatmap!') 203 | Title text. 204 | description : String, (default: 'Heatmap description') 205 | Description text of the heatmap. 206 | width : int, (default: 500). 207 | Width of the window. 208 | height : int, (default: 500). 209 | height of the window. 210 | fontsize : int, (default: 10). 211 | Font size for the X and Y labels. 212 | scale : Bool, (default: True). 213 | Scale the values between [0-100]. 214 | vmin : Bool, (default: 0). 215 | Range of colors starting with minimum value. 216 | * 1 : cells with value <1 are coloured white. 217 | * None : cells are colored based on the minimum value in the input data. 218 | vmax : Bool, (default: 100). 219 | Range of colors starting with maximum value. 220 | * 100 : cells above value >100 are capped. 221 | * None : cells are colored based on the maximum value in the input data. 222 | stroke : String, (default: 'red'). 223 | Color of the recangle when hovering over a cell. 224 | * 'red' 225 | * 'black' 226 | showfig : Bool, (default: True) 227 | Open browser with heatmap. 228 | overwrite : Bool, (default: False) 229 | Overwrite existing file on the path location. 230 | cmap : String, (default: 'interpolateInferno'). 231 | The colormap scheme. This can be found at: https://github.com/d3/d3-scale-chromatic. 232 | Categorical: 233 | * 'schemeCategory10' 234 | * 'schemeAccent' 235 | Diverging: 236 | * 'interpolateInferno' 237 | * 'interpolatePRGn' 238 | Single color: 239 | * 'interpolateBlues' 240 | * 'interpolateGreens' 241 | Sequential: 242 | * 'interpolateTurbo' 243 | * 'interpolateViridis' 244 | * 'interpolateInferno' 245 | Cyclic: 246 | * 'interpolateRainbow' 247 | * 'interpolateSinebow' 248 | verbose : int [0-5], (default: 3) 249 | Verbosity to print the working-status. The higher the number, the more information. 250 | * 0: None, 1: Error, 2: Warning, 3: Info, 4: Debug, 5: Trace 251 | 252 | Example 253 | ------- 254 | >>> # Load library 255 | >>> from d3heatmap import d3heatmap as d3 256 | >>> # Import example 257 | >>> df = d3.import_example(size=(6,20)) 258 | >>> # Create heatmap 259 | >>> paths = d3.matrix(df) 260 | >>> # The dataframe contains more columns then rows. Adjust the size and color differently. 261 | >>> paths = d3.matrix(df, fontsize=10, title='Hooray!', description='d3 matrix is created using https://github.com/erdogant/d3heatmap.', path='c:/temp/example/d3_matrix.html', width=600, height=300, cmap='interpolateGreens', vmin=1) 262 | 263 | Returns 264 | ------- 265 | out : dict. 266 | output path names. 267 | 268 | """ 269 | if cmap in ['schemeCategory10', 'schemeAccent', 'schemeDark2', 'schemePaired', 'schemePastel2', 'schemePastel1', 'schemeSet1', 'schemeSet2', 'schemeSet3', 'schemeTableau10']: 270 | cmap_type='scaleOrdinal' 271 | if verbose>=3: print('[d3heatmap] >d3 cmap type is set to %s' %(cmap_type)) 272 | else: 273 | cmap_type='scaleSequential' 274 | 275 | if len(df.columns.unique())!=len(df.columns): 276 | if verbose>=2: print('[d3heatmap] >Warning: Input data should contain unique column names otherwise d3js randomly removes the non-unique ones.') 277 | if len(df.index.unique())!=len(df.index): 278 | if verbose>=2: print('[d3heatmap] >Warning: Input data should contain unique index names otherwise d3js randomly removes the non-unique ones.') 279 | 280 | # Rescale data between 0-100 281 | if scale: 282 | df = _scale(df, verbose=verbose) 283 | if (not scale) and (vmin is not None) and (vmax is not None): 284 | if verbose>=3: print('[d3heatmap] >Data is not scaled. Tip: set vmin=None and vmax=None to range colors between min-max of your data.') 285 | if vmin is None: 286 | vmin = np.min(df.values) 287 | if vmax is None: 288 | vmax = np.max(df.values) 289 | if verbose>=3: print('[d3heatmap] >vmin is set to: %g' %(vmin)) 290 | if verbose>=3: print('[d3heatmap] >vmax is set to: %g' %(vmax)) 291 | 292 | # Get path to files 293 | d3_library = os.path.abspath(os.path.join(curpath, 'd3js/d3.v4.js')) 294 | d3_chromatic = os.path.abspath(os.path.join(curpath, 'd3js/d3.scale.chromatic.v1.min.js')) 295 | d3_script = os.path.abspath(os.path.join(curpath, 'd3js/d3script.html')) 296 | 297 | # Set fontsize for x-axis, y-axis 298 | fontsize_x = fontsize 299 | fontsize_y = fontsize 300 | 301 | # Check path 302 | filename, dirpath, path = _path_check(path, verbose) 303 | 304 | # Copy files to destination directory 305 | copyfile(d3_library, os.path.join(dirpath, os.path.basename(d3_library))) 306 | copyfile(d3_chromatic, os.path.join(dirpath, os.path.basename(d3_chromatic))) 307 | copyfile(d3_script, path) 308 | 309 | # Convert into adj into vector 310 | dfvec = adjmat2vec(df) 311 | dfvec = dfvec.rename(columns={'source': 'variable', 'target': 'group', 'weight': 'value'}) 312 | 313 | # Write to disk (file is not used) 314 | basename, ext = os.path.splitext(filename) 315 | PATHNAME_TO_CSV = os.path.join(dirpath, basename + '.csv') 316 | # dfvec.to_csv(PATHNAME_TO_CSV, index=False) 317 | 318 | # Embed the Data in the HTML. Note that the embedding is an important stap te prevent security issues by the browsers. 319 | # Most (if not all) browser do not accept to read a file using d3.csv or so. It then requires security-by-passes, but thats not the way to go. 320 | # An alternative is use local-host and CORS but then the approach is not user-friendly coz setting up this, is not so straightforward. 321 | # It leaves us by embedding the data in the HTML. Thats what we are going to do here. 322 | DATA_STR = '' 323 | for i in range(0, dfvec.shape[0]): 324 | newline = '{group : "' + str(dfvec['group'].iloc[i]) + '", variable : "' + str(dfvec['variable'].iloc[i]) + '", value : "' + str(dfvec['value'].iloc[i]) +'"},' 325 | newline = newline + '\n' 326 | DATA_STR = DATA_STR + newline 327 | 328 | # Read the data 329 | # var data = 330 | # [ 331 | # {"group":"A", "variable":"v1", "value":"3"}, 332 | # {"group":"A", "variable":"v2", "value":"5"}, 333 | # {"group":"B", "variable":"v1", "value":"10"}, 334 | # {"group":"B", "variable":"v2", "value":"10"} 335 | # ] 336 | 337 | # Import in the file 338 | with open(path, 'r') as file: d3graphscript = file.read() 339 | 340 | # Read the d3 html with script file 341 | d3graphscript = d3graphscript.replace('$DESCRIPTION$', str(description)) 342 | d3graphscript = d3graphscript.replace('$TITLE$', str(title)) 343 | 344 | d3graphscript = d3graphscript.replace('$WIDTH$', str(width)) 345 | d3graphscript = d3graphscript.replace('$HEIGHT$', str(height)) 346 | 347 | d3graphscript = d3graphscript.replace('$VMIN$', str(vmin)) 348 | d3graphscript = d3graphscript.replace('$VMAX$', str(vmax)) 349 | 350 | d3graphscript = d3graphscript.replace('$FONTSIZE_X$', str(fontsize_x)) 351 | d3graphscript = d3graphscript.replace('$FONTSIZE_Y$', str(fontsize_y)) 352 | 353 | d3graphscript = d3graphscript.replace('$STROKE$', str(stroke)) 354 | d3graphscript = d3graphscript.replace('$CMAP$', str(cmap)) 355 | d3graphscript = d3graphscript.replace('$CMAP_TYPE$', str(cmap_type)) 356 | 357 | d3graphscript = d3graphscript.replace('$DATA_PATH$', filename) 358 | d3graphscript = d3graphscript.replace('$DATA_COMES_HERE$', DATA_STR) 359 | 360 | # Delete file if exists 361 | if overwrite: 362 | os.remove(path) 363 | if os.path.isfile(path): 364 | if verbose>=2: print('[d3heatmap] >Warning: File already exists! Delete it manually or set the parameter "overwrite=True"') 365 | else: 366 | # Write to file 367 | if verbose>=3: print('[d3heatmap] >Writing to disk..') 368 | with open(path, 'w', encoding="utf8", errors='ignore') as file: file.write(d3graphscript) 369 | # Sleep a bit to make sure file is written 370 | time.sleep(0.5) 371 | # Open browser with heatmap 372 | if showfig: webbrowser.open(path, new=1) 373 | 374 | # Return 375 | out = {} 376 | out['filename'] = filename 377 | out['dirpath'] = dirpath 378 | out['path'] = path 379 | out['csv'] = PATHNAME_TO_CSV 380 | return out 381 | 382 | 383 | # %% Import example dataset from github. 384 | def import_example(size=(50, 50), verbose=3): 385 | """Generate example dataset. 386 | 387 | Description 388 | ----------- 389 | Generate random adjacency matrix. 390 | 391 | Parameters 392 | ---------- 393 | verbose : int, optional 394 | Print progress to screen. The default is 3. 395 | 0: None, 1: ERROR, 2: WARN, 3: INFO (default), 4: DEBUG, 5: TRACE 396 | 397 | Returns 398 | ------- 399 | pd.DataFrame() 400 | Dataset containing mixed features. 401 | 402 | """ 403 | df = pd.DataFrame(np.random.randint(0, 10, size=size)) 404 | 405 | # Return 406 | return df 407 | 408 | 409 | # %% 410 | def _path_check(path, verbose): 411 | # Check wether path 412 | if path is None: 413 | path = os.path.join(tempfile.gettempdir(), 'index.html') 414 | # Check wether dir + path 415 | dirpath, filename = os.path.split(path) 416 | # if input is single file, attach the absolute path. 417 | if dirpath=='': 418 | path = os.path.join(tempfile.gettempdir(), filename) 419 | dirpath, filename = os.path.split(path) 420 | # Check before proceeding 421 | if not ('.html' in filename): 422 | raise ValueError('[d3heatmap] >path should contain the file extension: ".html" ') 423 | # Create dir 424 | if not os.path.isdir(dirpath): 425 | if verbose>=2: print('[d3heatmap] >Warning: Creating directory [%s]' %(dirpath)) 426 | os.makedirs(dirpath, exist_ok=True) 427 | # Final 428 | path = os.path.abspath(path) 429 | dirpath, filename = os.path.split(path) 430 | return filename, dirpath, path 431 | 432 | 433 | # %% Scaling 434 | def _scale(X, vmax=100, make_round=True, verbose=3): 435 | """Scale data. 436 | 437 | Description 438 | ----------- 439 | Scaling in range by X*(100/max(X)) 440 | 441 | Parameters 442 | ---------- 443 | X : array-like 444 | Input image data. 445 | verbose : int (default : 3) 446 | Print to screen. 0: None, 1: Error, 2: Warning, 3: Info, 4: Debug, 5: Trace. 447 | 448 | Returns 449 | ------- 450 | df : array-like 451 | Scaled image. 452 | 453 | """ 454 | if verbose>=3: print('[d3heatmap] >Scaling image between [min-100]') 455 | try: 456 | # Normalizing between 0-100 457 | # X = X - X.min() 458 | X = X / X.max().max() 459 | X = X * vmax 460 | if make_round: 461 | X = np.round(X) 462 | except: 463 | if verbose>=2: print('[d3heatmap] >Warning: Scaling not possible.') 464 | 465 | return X 466 | 467 | 468 | # %% Convert adjacency matrix to vector 469 | def vec2adjmat(source, target, weight=None, symmetric=True): 470 | """Convert source and target into adjacency matrix. 471 | 472 | Parameters 473 | ---------- 474 | source : list 475 | The source node. 476 | target : list 477 | The target node. 478 | weight : list of int 479 | The Weights between the source-target values 480 | symmetric : bool, optional 481 | Make the adjacency matrix symmetric with the same number of rows as columns. The default is True. 482 | 483 | Returns 484 | ------- 485 | pd.DataFrame 486 | adjacency matrix. 487 | 488 | Examples 489 | -------- 490 | >>> source=['Cloudy','Cloudy','Sprinkler','Rain'] 491 | >>> target=['Sprinkler','Rain','Wet_Grass','Wet_Grass'] 492 | >>> vec2adjmat(source, target) 493 | >>> 494 | >>> weight=[1,2,1,3] 495 | >>> vec2adjmat(source, target, weight=weight) 496 | 497 | """ 498 | if len(source)!=len(target): raise Exception('[hnet] >Source and Target should have equal elements.') 499 | if weight is None: weight = [1]*len(source) 500 | 501 | df = pd.DataFrame(np.c_[source, target], columns=['source','target']) 502 | # Make adjacency matrix 503 | adjmat = pd.crosstab(df['source'], df['target'], values=weight, aggfunc='sum').fillna(0) 504 | # Get all unique nodes 505 | nodes = np.unique(list(adjmat.columns.values)+list(adjmat.index.values)) 506 | # nodes = np.unique(np.c_[adjmat.columns.values, adjmat.index.values].flatten()) 507 | 508 | # Make the adjacency matrix symmetric 509 | if symmetric: 510 | # Add missing columns 511 | node_columns = np.setdiff1d(nodes, adjmat.columns.values) 512 | for node in node_columns: 513 | adjmat[node]=0 514 | 515 | # Add missing rows 516 | node_rows = np.setdiff1d(nodes, adjmat.index.values) 517 | adjmat=adjmat.T 518 | for node in node_rows: 519 | adjmat[node]=0 520 | adjmat=adjmat.T 521 | 522 | # Sort to make ordering of columns and rows similar 523 | [IA, IB] = ismember(adjmat.columns.values, adjmat.index.values) 524 | adjmat = adjmat.iloc[IB, :] 525 | adjmat.index.name='source' 526 | adjmat.columns.name='target' 527 | 528 | return(adjmat) 529 | 530 | 531 | # %% Convert adjacency matrix to vector 532 | def adjmat2vec(adjmat, min_weight=0, verbose=3): 533 | """Convert adjacency matrix into vector with source and target. 534 | 535 | Parameters 536 | ---------- 537 | adjmat : pd.DataFrame() 538 | Adjacency matrix. 539 | 540 | min_weight : float 541 | edges are returned with a minimum weight. 542 | 543 | Returns 544 | ------- 545 | pd.DataFrame() 546 | nodes that are connected based on source and target 547 | 548 | Examples 549 | -------- 550 | >>> source=['Cloudy','Cloudy','Sprinkler','Rain'] 551 | >>> target=['Sprinkler','Rain','Wet_Grass','Wet_Grass'] 552 | >>> adjmat = vec2adjmat(source, target) 553 | >>> vector = adjmat2vec(adjmat) 554 | 555 | """ 556 | # Convert adjacency matrix into vector 557 | adjmat = adjmat.stack().reset_index() 558 | # Set columns 559 | adjmat.columns = ['source', 'target', 'weight'] 560 | # Remove self loops and no-connected edges 561 | # Iloc1 = adjmat['source']!=adjmat['target'] 562 | Iloc2 = adjmat['weight']>=min_weight 563 | # Iloc = Iloc1 & Iloc2 564 | Iloc = Iloc2 565 | # Take only connected nodes 566 | adjmat = adjmat.loc[Iloc, :] 567 | adjmat.reset_index(drop=True, inplace=True) 568 | return(adjmat) -------------------------------------------------------------------------------- /d3heatmap/d3js/d3heatmap.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | "$TITLE$" 14 | 229 | 230 | 231 | 232 | 238 | 239 | 240 |

$TITLE$

241 | 242 | 251 | 252 | 418 | 419 |

$DESCRIPTION$ 420 | --------------------------------------------------------------------------------