Mock Version: 2.15 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', 'e55e3d31560d44ca8da792c237241dfe', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -bs --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1642809600 Wrote: /builddir/build/SRPMS/python-easyplotly-0.1.3-1.fc36.src.rpm Child return code was: 0 ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '33c0d73a20ea4943aa70d334711cede1', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1642809600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.75Unr1 + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf easyplotly-0.1.3 + /usr/bin/gzip -dc /builddir/build/SOURCES/easyplotly-0.1.3.tar.gz + /usr/bin/tar -xof - + STATUS=0 + '[' 0 -ne 0 ']' + cd easyplotly-0.1.3 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.yUu8tZ + umask 022 + cd /builddir/build/BUILD + cd easyplotly-0.1.3 + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement not satisfied: setuptools >= 40.8 Handling wheel from default build backend Requirement not satisfied: wheel Exiting dependency generation pass: build backend + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-easyplotly-0.1.3-1.fc36.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '5cd073bb436a490e8e5da2854cd41302', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1642809600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.LTIPyx + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf easyplotly-0.1.3 + /usr/bin/gzip -dc /builddir/build/SOURCES/easyplotly-0.1.3.tar.gz + /usr/bin/tar -xof - + STATUS=0 + '[' 0 -ne 0 ']' + cd easyplotly-0.1.3 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.KPRss7 + umask 022 + cd /builddir/build/BUILD + cd easyplotly-0.1.3 + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement satisfied: setuptools >= 40.8 (installed: setuptools 59.6.0) Handling wheel from default build backend Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: # Easy Plotly HOOK STDOUT: HOOK STDOUT: [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) HOOK STDOUT: [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) HOOK STDOUT: [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) HOOK STDOUT: [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( HOOK STDOUT: https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) HOOK STDOUT: [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) HOOK STDOUT: Star HOOK STDOUT: HOOK STDOUT: This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), HOOK STDOUT: especially ploting of hierarchical data, could be made easier. HOOK STDOUT: HOOK STDOUT: See the outputs of the commands below - tables and plots - HOOK STDOUT: in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. HOOK STDOUT: Or even, open this `README.md` as a notebook and run it interactively on HOOK STDOUT: [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! HOOK STDOUT: HOOK STDOUT: ## Installation HOOK STDOUT: HOOK STDOUT: Install the `easyplotly` python package with HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: pip install easyplotly HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sample data HOOK STDOUT: HOOK STDOUT: Our sample data is the population and life expectancy, per country and region: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import world_bank_data as wb HOOK STDOUT: import itables.interactive HOOK STDOUT: HOOK STDOUT: # Collect countries HOOK STDOUT: countries = wb.get_countries() HOOK STDOUT: region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) HOOK STDOUT: HOOK STDOUT: # Population & life expectancy HOOK STDOUT: region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: HOOK STDOUT: # Observations restricted to the countries HOOK STDOUT: pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() HOOK STDOUT: pop_and_exp HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sunburst Charts HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import plotly.graph_objects as go HOOK STDOUT: import plotly.io as pio HOOK STDOUT: import easyplotly as ep HOOK STDOUT: HOOK STDOUT: pio.renderers.default = 'notebook_connected' HOOK STDOUT: layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. HOOK STDOUT: If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index HOOK STDOUT: identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` HOOK STDOUT: associates the corresponding label or value. HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(sunburst, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Treemaps HOOK STDOUT: HOOK STDOUT: The `Treemap` function works like the `Sunburst` one: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Just like the `Sunburst` function, it also accepts all the arguments supported by the original HOOK STDOUT: `go.Sunburst` object. You're even welcome to use the HOOK STDOUT: [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), HOOK STDOUT: as we do below when we set `marker.colors` with `marker_colors`: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import numpy as np HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def average(values, weights): HOOK STDOUT: """Same as np.average, but remove nans""" HOOK STDOUT: total_obs = 0. HOOK STDOUT: total_weight = 0. HOOK STDOUT: if isinstance(values, np.float): HOOK STDOUT: values = [values] HOOK STDOUT: weights = [weights] HOOK STDOUT: for x, w in zip(values, weights): HOOK STDOUT: xw = x * w HOOK STDOUT: if np.isnan(xw): HOOK STDOUT: continue HOOK STDOUT: total_obs += xw HOOK STDOUT: total_weight += w HOOK STDOUT: return total_obs / total_weight if total_weight != 0 else np.NaN HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def life_expectancy(item): HOOK STDOUT: """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: sub = pop_and_exp.loc[item] if item else pop_and_exp HOOK STDOUT: return average(sub.life_expectancy, weights=sub.population) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def text(item): HOOK STDOUT: """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: life_exp = life_expectancy(item) HOOK STDOUT: if life_exp > 0: HOOK STDOUT: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() HOOK STDOUT: return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, HOOK STDOUT: hoverinfo='label+text', HOOK STDOUT: text=text, HOOK STDOUT: root_label='World', HOOK STDOUT: # magic underscore notation HOOK STDOUT: marker_colors=life_expectancy, HOOK STDOUT: marker_colorscale='RdBu') HOOK STDOUT: HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sankey Plot HOOK STDOUT: HOOK STDOUT: Plot links from a dict, or a series with a source/target multiindex: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Plot links from a DataFrame (sources as the index, targets as the columns): HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import pandas as pd HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: We conclude the examples with a plot in which the links are a list of pandas Series: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: region_income = wb.get_countries().query("region != 'Aggregates'").copy() HOOK STDOUT: region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: income_lending = region_income.copy() HOOK STDOUT: region_income.set_index(['region', 'incomeLevel'], inplace=True) HOOK STDOUT: income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) HOOK STDOUT: HOOK STDOUT: layout = go.Layout(title='Regions income and lending type
Data from the World Bank') HOOK STDOUT: HOOK STDOUT: sankey = ep.Sankey( HOOK STDOUT: link_value=[region_income['population'], income_lending['population']], HOOK STDOUT: link_label=[region_income['name'], income_lending['name']]) HOOK STDOUT: HOOK STDOUT: go.Figure(sankey, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: running egg_info HOOK STDOUT: writing easyplotly.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to easyplotly.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to easyplotly.egg-info/requires.txt HOOK STDOUT: writing top-level names to easyplotly.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'easyplotly.egg-info/SOURCES.txt' Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: # Easy Plotly HOOK STDOUT: HOOK STDOUT: [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) HOOK STDOUT: [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) HOOK STDOUT: [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) HOOK STDOUT: [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( HOOK STDOUT: https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) HOOK STDOUT: [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) HOOK STDOUT: Star HOOK STDOUT: HOOK STDOUT: This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), HOOK STDOUT: especially ploting of hierarchical data, could be made easier. HOOK STDOUT: HOOK STDOUT: See the outputs of the commands below - tables and plots - HOOK STDOUT: in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. HOOK STDOUT: Or even, open this `README.md` as a notebook and run it interactively on HOOK STDOUT: [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! HOOK STDOUT: HOOK STDOUT: ## Installation HOOK STDOUT: HOOK STDOUT: Install the `easyplotly` python package with HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: pip install easyplotly HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sample data HOOK STDOUT: HOOK STDOUT: Our sample data is the population and life expectancy, per country and region: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import world_bank_data as wb HOOK STDOUT: import itables.interactive HOOK STDOUT: HOOK STDOUT: # Collect countries HOOK STDOUT: countries = wb.get_countries() HOOK STDOUT: region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) HOOK STDOUT: HOOK STDOUT: # Population & life expectancy HOOK STDOUT: region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: HOOK STDOUT: # Observations restricted to the countries HOOK STDOUT: pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() HOOK STDOUT: pop_and_exp HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sunburst Charts HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import plotly.graph_objects as go HOOK STDOUT: import plotly.io as pio HOOK STDOUT: import easyplotly as ep HOOK STDOUT: HOOK STDOUT: pio.renderers.default = 'notebook_connected' HOOK STDOUT: layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. HOOK STDOUT: If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index HOOK STDOUT: identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` HOOK STDOUT: associates the corresponding label or value. HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(sunburst, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Treemaps HOOK STDOUT: HOOK STDOUT: The `Treemap` function works like the `Sunburst` one: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Just like the `Sunburst` function, it also accepts all the arguments supported by the original HOOK STDOUT: `go.Sunburst` object. You're even welcome to use the HOOK STDOUT: [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), HOOK STDOUT: as we do below when we set `marker.colors` with `marker_colors`: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import numpy as np HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def average(values, weights): HOOK STDOUT: """Same as np.average, but remove nans""" HOOK STDOUT: total_obs = 0. HOOK STDOUT: total_weight = 0. HOOK STDOUT: if isinstance(values, np.float): HOOK STDOUT: values = [values] HOOK STDOUT: weights = [weights] HOOK STDOUT: for x, w in zip(values, weights): HOOK STDOUT: xw = x * w HOOK STDOUT: if np.isnan(xw): HOOK STDOUT: continue HOOK STDOUT: total_obs += xw HOOK STDOUT: total_weight += w HOOK STDOUT: return total_obs / total_weight if total_weight != 0 else np.NaN HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def life_expectancy(item): HOOK STDOUT: """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: sub = pop_and_exp.loc[item] if item else pop_and_exp HOOK STDOUT: return average(sub.life_expectancy, weights=sub.population) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def text(item): HOOK STDOUT: """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: life_exp = life_expectancy(item) HOOK STDOUT: if life_exp > 0: HOOK STDOUT: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() HOOK STDOUT: return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, HOOK STDOUT: hoverinfo='label+text', HOOK STDOUT: text=text, HOOK STDOUT: root_label='World', HOOK STDOUT: # magic underscore notation HOOK STDOUT: marker_colors=life_expectancy, HOOK STDOUT: marker_colorscale='RdBu') HOOK STDOUT: HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sankey Plot HOOK STDOUT: HOOK STDOUT: Plot links from a dict, or a series with a source/target multiindex: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Plot links from a DataFrame (sources as the index, targets as the columns): HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import pandas as pd HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: We conclude the examples with a plot in which the links are a list of pandas Series: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: region_income = wb.get_countries().query("region != 'Aggregates'").copy() HOOK STDOUT: region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: income_lending = region_income.copy() HOOK STDOUT: region_income.set_index(['region', 'incomeLevel'], inplace=True) HOOK STDOUT: income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) HOOK STDOUT: HOOK STDOUT: layout = go.Layout(title='Regions income and lending type
Data from the World Bank') HOOK STDOUT: HOOK STDOUT: sankey = ep.Sankey( HOOK STDOUT: link_value=[region_income['population'], income_lending['population']], HOOK STDOUT: link_label=[region_income['name'], income_lending['name']]) HOOK STDOUT: HOOK STDOUT: go.Figure(sankey, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: running dist_info HOOK STDOUT: writing easyplotly.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to easyplotly.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to easyplotly.egg-info/requires.txt HOOK STDOUT: writing top-level names to easyplotly.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: creating '/builddir/build/BUILD/easyplotly-0.1.3/easyplotly.dist-info' HOOK STDOUT: adding license file "LICENSE" (matched pattern "LICEN[CS]E*") Handling pandas from wheel metadata: Requires-Dist Requirement not satisfied: pandas Handling numpy from wheel metadata: Requires-Dist Requirement not satisfied: numpy Handling plotly from wheel metadata: Requires-Dist Requirement not satisfied: plotly + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-easyplotly-0.1.3-1.fc36.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueraiseExc=FalseprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', '89288abaf5bb41fabc7860c9ecba8b0f', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -br --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1642809600 Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.mvez0B + umask 022 + cd /builddir/build/BUILD + cd /builddir/build/BUILD + rm -rf easyplotly-0.1.3 + /usr/bin/gzip -dc /builddir/build/SOURCES/easyplotly-0.1.3.tar.gz + /usr/bin/tar -xof - + STATUS=0 + '[' 0 -ne 0 ']' + cd easyplotly-0.1.3 + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . + RPM_EC=0 ++ jobs -p + exit 0 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.QrG8gL + umask 022 + cd /builddir/build/BUILD + cd easyplotly-0.1.3 + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv '*.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement satisfied: setuptools >= 40.8 (installed: setuptools 59.6.0) Handling wheel from default build backend Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: # Easy Plotly HOOK STDOUT: HOOK STDOUT: [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) HOOK STDOUT: [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) HOOK STDOUT: [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) HOOK STDOUT: [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( HOOK STDOUT: https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) HOOK STDOUT: [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) HOOK STDOUT: Star HOOK STDOUT: HOOK STDOUT: This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), HOOK STDOUT: especially ploting of hierarchical data, could be made easier. HOOK STDOUT: HOOK STDOUT: See the outputs of the commands below - tables and plots - HOOK STDOUT: in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. HOOK STDOUT: Or even, open this `README.md` as a notebook and run it interactively on HOOK STDOUT: [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! HOOK STDOUT: HOOK STDOUT: ## Installation HOOK STDOUT: HOOK STDOUT: Install the `easyplotly` python package with HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: pip install easyplotly HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sample data HOOK STDOUT: HOOK STDOUT: Our sample data is the population and life expectancy, per country and region: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import world_bank_data as wb HOOK STDOUT: import itables.interactive HOOK STDOUT: HOOK STDOUT: # Collect countries HOOK STDOUT: countries = wb.get_countries() HOOK STDOUT: region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) HOOK STDOUT: HOOK STDOUT: # Population & life expectancy HOOK STDOUT: region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: HOOK STDOUT: # Observations restricted to the countries HOOK STDOUT: pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() HOOK STDOUT: pop_and_exp HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sunburst Charts HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import plotly.graph_objects as go HOOK STDOUT: import plotly.io as pio HOOK STDOUT: import easyplotly as ep HOOK STDOUT: HOOK STDOUT: pio.renderers.default = 'notebook_connected' HOOK STDOUT: layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. HOOK STDOUT: If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index HOOK STDOUT: identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` HOOK STDOUT: associates the corresponding label or value. HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(sunburst, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Treemaps HOOK STDOUT: HOOK STDOUT: The `Treemap` function works like the `Sunburst` one: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Just like the `Sunburst` function, it also accepts all the arguments supported by the original HOOK STDOUT: `go.Sunburst` object. You're even welcome to use the HOOK STDOUT: [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), HOOK STDOUT: as we do below when we set `marker.colors` with `marker_colors`: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import numpy as np HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def average(values, weights): HOOK STDOUT: """Same as np.average, but remove nans""" HOOK STDOUT: total_obs = 0. HOOK STDOUT: total_weight = 0. HOOK STDOUT: if isinstance(values, np.float): HOOK STDOUT: values = [values] HOOK STDOUT: weights = [weights] HOOK STDOUT: for x, w in zip(values, weights): HOOK STDOUT: xw = x * w HOOK STDOUT: if np.isnan(xw): HOOK STDOUT: continue HOOK STDOUT: total_obs += xw HOOK STDOUT: total_weight += w HOOK STDOUT: return total_obs / total_weight if total_weight != 0 else np.NaN HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def life_expectancy(item): HOOK STDOUT: """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: sub = pop_and_exp.loc[item] if item else pop_and_exp HOOK STDOUT: return average(sub.life_expectancy, weights=sub.population) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def text(item): HOOK STDOUT: """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: life_exp = life_expectancy(item) HOOK STDOUT: if life_exp > 0: HOOK STDOUT: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() HOOK STDOUT: return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, HOOK STDOUT: hoverinfo='label+text', HOOK STDOUT: text=text, HOOK STDOUT: root_label='World', HOOK STDOUT: # magic underscore notation HOOK STDOUT: marker_colors=life_expectancy, HOOK STDOUT: marker_colorscale='RdBu') HOOK STDOUT: HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sankey Plot HOOK STDOUT: HOOK STDOUT: Plot links from a dict, or a series with a source/target multiindex: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Plot links from a DataFrame (sources as the index, targets as the columns): HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import pandas as pd HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: We conclude the examples with a plot in which the links are a list of pandas Series: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: region_income = wb.get_countries().query("region != 'Aggregates'").copy() HOOK STDOUT: region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: income_lending = region_income.copy() HOOK STDOUT: region_income.set_index(['region', 'incomeLevel'], inplace=True) HOOK STDOUT: income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) HOOK STDOUT: HOOK STDOUT: layout = go.Layout(title='Regions income and lending type
Data from the World Bank') HOOK STDOUT: HOOK STDOUT: sankey = ep.Sankey( HOOK STDOUT: link_value=[region_income['population'], income_lending['population']], HOOK STDOUT: link_label=[region_income['name'], income_lending['name']]) HOOK STDOUT: HOOK STDOUT: go.Figure(sankey, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: running egg_info HOOK STDOUT: writing easyplotly.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to easyplotly.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to easyplotly.egg-info/requires.txt HOOK STDOUT: writing top-level names to easyplotly.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'easyplotly.egg-info/SOURCES.txt' Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: # Easy Plotly HOOK STDOUT: HOOK STDOUT: [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) HOOK STDOUT: [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) HOOK STDOUT: [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) HOOK STDOUT: [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( HOOK STDOUT: https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) HOOK STDOUT: [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) HOOK STDOUT: Star HOOK STDOUT: HOOK STDOUT: This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), HOOK STDOUT: especially ploting of hierarchical data, could be made easier. HOOK STDOUT: HOOK STDOUT: See the outputs of the commands below - tables and plots - HOOK STDOUT: in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. HOOK STDOUT: Or even, open this `README.md` as a notebook and run it interactively on HOOK STDOUT: [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! HOOK STDOUT: HOOK STDOUT: ## Installation HOOK STDOUT: HOOK STDOUT: Install the `easyplotly` python package with HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: pip install easyplotly HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sample data HOOK STDOUT: HOOK STDOUT: Our sample data is the population and life expectancy, per country and region: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import world_bank_data as wb HOOK STDOUT: import itables.interactive HOOK STDOUT: HOOK STDOUT: # Collect countries HOOK STDOUT: countries = wb.get_countries() HOOK STDOUT: region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) HOOK STDOUT: HOOK STDOUT: # Population & life expectancy HOOK STDOUT: region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: HOOK STDOUT: # Observations restricted to the countries HOOK STDOUT: pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() HOOK STDOUT: pop_and_exp HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sunburst Charts HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import plotly.graph_objects as go HOOK STDOUT: import plotly.io as pio HOOK STDOUT: import easyplotly as ep HOOK STDOUT: HOOK STDOUT: pio.renderers.default = 'notebook_connected' HOOK STDOUT: layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. HOOK STDOUT: If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index HOOK STDOUT: identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` HOOK STDOUT: associates the corresponding label or value. HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(sunburst, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Treemaps HOOK STDOUT: HOOK STDOUT: The `Treemap` function works like the `Sunburst` one: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Just like the `Sunburst` function, it also accepts all the arguments supported by the original HOOK STDOUT: `go.Sunburst` object. You're even welcome to use the HOOK STDOUT: [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), HOOK STDOUT: as we do below when we set `marker.colors` with `marker_colors`: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import numpy as np HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def average(values, weights): HOOK STDOUT: """Same as np.average, but remove nans""" HOOK STDOUT: total_obs = 0. HOOK STDOUT: total_weight = 0. HOOK STDOUT: if isinstance(values, np.float): HOOK STDOUT: values = [values] HOOK STDOUT: weights = [weights] HOOK STDOUT: for x, w in zip(values, weights): HOOK STDOUT: xw = x * w HOOK STDOUT: if np.isnan(xw): HOOK STDOUT: continue HOOK STDOUT: total_obs += xw HOOK STDOUT: total_weight += w HOOK STDOUT: return total_obs / total_weight if total_weight != 0 else np.NaN HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def life_expectancy(item): HOOK STDOUT: """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: sub = pop_and_exp.loc[item] if item else pop_and_exp HOOK STDOUT: return average(sub.life_expectancy, weights=sub.population) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def text(item): HOOK STDOUT: """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: life_exp = life_expectancy(item) HOOK STDOUT: if life_exp > 0: HOOK STDOUT: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() HOOK STDOUT: return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, HOOK STDOUT: hoverinfo='label+text', HOOK STDOUT: text=text, HOOK STDOUT: root_label='World', HOOK STDOUT: # magic underscore notation HOOK STDOUT: marker_colors=life_expectancy, HOOK STDOUT: marker_colorscale='RdBu') HOOK STDOUT: HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sankey Plot HOOK STDOUT: HOOK STDOUT: Plot links from a dict, or a series with a source/target multiindex: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Plot links from a DataFrame (sources as the index, targets as the columns): HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import pandas as pd HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: We conclude the examples with a plot in which the links are a list of pandas Series: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: region_income = wb.get_countries().query("region != 'Aggregates'").copy() HOOK STDOUT: region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: income_lending = region_income.copy() HOOK STDOUT: region_income.set_index(['region', 'incomeLevel'], inplace=True) HOOK STDOUT: income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) HOOK STDOUT: HOOK STDOUT: layout = go.Layout(title='Regions income and lending type
Data from the World Bank') HOOK STDOUT: HOOK STDOUT: sankey = ep.Sankey( HOOK STDOUT: link_value=[region_income['population'], income_lending['population']], HOOK STDOUT: link_label=[region_income['name'], income_lending['name']]) HOOK STDOUT: HOOK STDOUT: go.Figure(sankey, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: running dist_info HOOK STDOUT: writing easyplotly.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to easyplotly.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to easyplotly.egg-info/requires.txt HOOK STDOUT: writing top-level names to easyplotly.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: creating '/builddir/build/BUILD/easyplotly-0.1.3/easyplotly.dist-info' HOOK STDOUT: adding license file "LICENSE" (matched pattern "LICEN[CS]E*") Handling pandas from wheel metadata: Requires-Dist Requirement satisfied: pandas (installed: pandas 1.3.3) Handling numpy from wheel metadata: Requires-Dist Requirement satisfied: numpy (installed: numpy 1.22.0) Handling plotly from wheel metadata: Requires-Dist Requirement satisfied: plotly (installed: plotly 4.14.3) + RPM_EC=0 ++ jobs -p + exit 0 Wrote: /builddir/build/SRPMS/python-easyplotly-0.1.3-1.fc36.buildreqs.nosrc.rpm Child return code was: 11 Dynamic buildrequires detected Going to install missing buildrequires. See root.log for details. ENTER ['do_with_status'](['bash', '--login', '-c', '/usr/bin/rpmbuild -ba --noprep --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'], chrootPath='/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root'env={'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8'}shell=Falselogger=timeout=0uid=1000gid=135user='mockbuild'nspawn_args=['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11']unshare_net=TrueprintOutput=True) Using nspawn with args ['--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11'] Executing command: ['/usr/bin/systemd-nspawn', '-q', '-M', 'e58e10599aeb4a53a73ffdc77898f3f4', '-D', '/var/lib/mock/fedora-rawhide-x86_64-1642986183.897545/root', '-a', '-u', 'mockbuild', '--capability=cap_ipc_lock', '--rlimit=RLIMIT_NOFILE=10240', '--capability=cap_ipc_lock', '--bind=/tmp/mock-resolv.qctgb2p7:/etc/resolv.conf', '--bind=/dev/btrfs-control', '--bind=/dev/loop-control', '--bind=/dev/loop0', '--bind=/dev/loop1', '--bind=/dev/loop2', '--bind=/dev/loop3', '--bind=/dev/loop4', '--bind=/dev/loop5', '--bind=/dev/loop6', '--bind=/dev/loop7', '--bind=/dev/loop8', '--bind=/dev/loop9', '--bind=/dev/loop10', '--bind=/dev/loop11', '--console=pipe', '--setenv=TERM=vt100', '--setenv=SHELL=/bin/bash', '--setenv=HOME=/builddir', '--setenv=HOSTNAME=mock', '--setenv=PATH=/usr/bin:/bin:/usr/sbin:/sbin', '--setenv=PROMPT_COMMAND=printf "\\033]0;\\007"', '--setenv=PS1= \\s-\\v\\$ ', '--setenv=LANG=C.UTF-8', '--resolv-conf=off', 'bash', '--login', '-c', '/usr/bin/rpmbuild -ba --noprep --target x86_64 --nodeps /builddir/build/SPECS/python-easyplotly.spec'] with env {'TERM': 'vt100', 'SHELL': '/bin/bash', 'HOME': '/builddir', 'HOSTNAME': 'mock', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin', 'PROMPT_COMMAND': 'printf "\\033]0;\\007"', 'PS1': ' \\s-\\v\\$ ', 'LANG': 'C.UTF-8', 'SYSTEMD_NSPAWN_TMPFS_TMP': '0'} and shell False Building target platforms: x86_64 Building for target x86_64 setting SOURCE_DATE_EPOCH=1642809600 Executing(%generate_buildrequires): /bin/sh -e /var/tmp/rpm-tmp.aWaoWJ + umask 022 + cd /builddir/build/BUILD + cd easyplotly-0.1.3 + echo python3-devel + echo 'python3dist(pip) >= 19' + echo 'python3dist(packaging)' + '[' -f pyproject.toml ']' + '[' -f setup.py ']' + echo 'python3dist(setuptools) >= 40.8' + echo 'python3dist(wheel)' + rm -rfv easyplotly.dist-info/ removed 'easyplotly.dist-info/LICENSE' removed 'easyplotly.dist-info/METADATA' removed 'easyplotly.dist-info/top_level.txt' removed directory 'easyplotly.dist-info/' + '[' -f /usr/bin/python3 ']' + RPM_TOXENV=py310 + HOSTNAME=rpmbuild + /usr/bin/python3 -s /usr/lib/rpm/redhat/pyproject_buildrequires.py --generate-extras --python3_pkgversion 3 -r Handling setuptools >= 40.8 from default build backend Requirement satisfied: setuptools >= 40.8 (installed: setuptools 59.6.0) Handling wheel from default build backend Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: # Easy Plotly HOOK STDOUT: HOOK STDOUT: [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) HOOK STDOUT: [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) HOOK STDOUT: [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) HOOK STDOUT: [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( HOOK STDOUT: https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) HOOK STDOUT: [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) HOOK STDOUT: Star HOOK STDOUT: HOOK STDOUT: This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), HOOK STDOUT: especially ploting of hierarchical data, could be made easier. HOOK STDOUT: HOOK STDOUT: See the outputs of the commands below - tables and plots - HOOK STDOUT: in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. HOOK STDOUT: Or even, open this `README.md` as a notebook and run it interactively on HOOK STDOUT: [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! HOOK STDOUT: HOOK STDOUT: ## Installation HOOK STDOUT: HOOK STDOUT: Install the `easyplotly` python package with HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: pip install easyplotly HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sample data HOOK STDOUT: HOOK STDOUT: Our sample data is the population and life expectancy, per country and region: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import world_bank_data as wb HOOK STDOUT: import itables.interactive HOOK STDOUT: HOOK STDOUT: # Collect countries HOOK STDOUT: countries = wb.get_countries() HOOK STDOUT: region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) HOOK STDOUT: HOOK STDOUT: # Population & life expectancy HOOK STDOUT: region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: HOOK STDOUT: # Observations restricted to the countries HOOK STDOUT: pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() HOOK STDOUT: pop_and_exp HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sunburst Charts HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import plotly.graph_objects as go HOOK STDOUT: import plotly.io as pio HOOK STDOUT: import easyplotly as ep HOOK STDOUT: HOOK STDOUT: pio.renderers.default = 'notebook_connected' HOOK STDOUT: layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. HOOK STDOUT: If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index HOOK STDOUT: identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` HOOK STDOUT: associates the corresponding label or value. HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(sunburst, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Treemaps HOOK STDOUT: HOOK STDOUT: The `Treemap` function works like the `Sunburst` one: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Just like the `Sunburst` function, it also accepts all the arguments supported by the original HOOK STDOUT: `go.Sunburst` object. You're even welcome to use the HOOK STDOUT: [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), HOOK STDOUT: as we do below when we set `marker.colors` with `marker_colors`: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import numpy as np HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def average(values, weights): HOOK STDOUT: """Same as np.average, but remove nans""" HOOK STDOUT: total_obs = 0. HOOK STDOUT: total_weight = 0. HOOK STDOUT: if isinstance(values, np.float): HOOK STDOUT: values = [values] HOOK STDOUT: weights = [weights] HOOK STDOUT: for x, w in zip(values, weights): HOOK STDOUT: xw = x * w HOOK STDOUT: if np.isnan(xw): HOOK STDOUT: continue HOOK STDOUT: total_obs += xw HOOK STDOUT: total_weight += w HOOK STDOUT: return total_obs / total_weight if total_weight != 0 else np.NaN HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def life_expectancy(item): HOOK STDOUT: """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: sub = pop_and_exp.loc[item] if item else pop_and_exp HOOK STDOUT: return average(sub.life_expectancy, weights=sub.population) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def text(item): HOOK STDOUT: """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: life_exp = life_expectancy(item) HOOK STDOUT: if life_exp > 0: HOOK STDOUT: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() HOOK STDOUT: return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, HOOK STDOUT: hoverinfo='label+text', HOOK STDOUT: text=text, HOOK STDOUT: root_label='World', HOOK STDOUT: # magic underscore notation HOOK STDOUT: marker_colors=life_expectancy, HOOK STDOUT: marker_colorscale='RdBu') HOOK STDOUT: HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sankey Plot HOOK STDOUT: HOOK STDOUT: Plot links from a dict, or a series with a source/target multiindex: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Plot links from a DataFrame (sources as the index, targets as the columns): HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import pandas as pd HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: We conclude the examples with a plot in which the links are a list of pandas Series: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: region_income = wb.get_countries().query("region != 'Aggregates'").copy() HOOK STDOUT: region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: income_lending = region_income.copy() HOOK STDOUT: region_income.set_index(['region', 'incomeLevel'], inplace=True) HOOK STDOUT: income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) HOOK STDOUT: HOOK STDOUT: layout = go.Layout(title='Regions income and lending type
Data from the World Bank') HOOK STDOUT: HOOK STDOUT: sankey = ep.Sankey( HOOK STDOUT: link_value=[region_income['population'], income_lending['population']], HOOK STDOUT: link_label=[region_income['name'], income_lending['name']]) HOOK STDOUT: HOOK STDOUT: go.Figure(sankey, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: running egg_info HOOK STDOUT: creating easyplotly.egg-info HOOK STDOUT: writing easyplotly.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to easyplotly.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to easyplotly.egg-info/requires.txt HOOK STDOUT: writing top-level names to easyplotly.egg-info/top_level.txt HOOK STDOUT: writing manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: reading manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'easyplotly.egg-info/SOURCES.txt' Handling wheel from get_requires_for_build_wheel Requirement satisfied: wheel (installed: wheel 0.37.0) HOOK STDOUT: # Easy Plotly HOOK STDOUT: HOOK STDOUT: [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) HOOK STDOUT: [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) HOOK STDOUT: [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) HOOK STDOUT: [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) HOOK STDOUT: [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( HOOK STDOUT: https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) HOOK STDOUT: [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) HOOK STDOUT: Star HOOK STDOUT: HOOK STDOUT: This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), HOOK STDOUT: especially ploting of hierarchical data, could be made easier. HOOK STDOUT: HOOK STDOUT: See the outputs of the commands below - tables and plots - HOOK STDOUT: in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. HOOK STDOUT: Or even, open this `README.md` as a notebook and run it interactively on HOOK STDOUT: [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! HOOK STDOUT: HOOK STDOUT: ## Installation HOOK STDOUT: HOOK STDOUT: Install the `easyplotly` python package with HOOK STDOUT: HOOK STDOUT: ``` HOOK STDOUT: pip install easyplotly HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sample data HOOK STDOUT: HOOK STDOUT: Our sample data is the population and life expectancy, per country and region: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import world_bank_data as wb HOOK STDOUT: import itables.interactive HOOK STDOUT: HOOK STDOUT: # Collect countries HOOK STDOUT: countries = wb.get_countries() HOOK STDOUT: region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) HOOK STDOUT: HOOK STDOUT: # Population & life expectancy HOOK STDOUT: region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: HOOK STDOUT: # Observations restricted to the countries HOOK STDOUT: pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() HOOK STDOUT: pop_and_exp HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sunburst Charts HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import plotly.graph_objects as go HOOK STDOUT: import plotly.io as pio HOOK STDOUT: import easyplotly as ep HOOK STDOUT: HOOK STDOUT: pio.renderers.default = 'notebook_connected' HOOK STDOUT: layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. HOOK STDOUT: If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index HOOK STDOUT: identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` HOOK STDOUT: associates the corresponding label or value. HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(sunburst, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Treemaps HOOK STDOUT: HOOK STDOUT: The `Treemap` function works like the `Sunburst` one: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Just like the `Sunburst` function, it also accepts all the arguments supported by the original HOOK STDOUT: `go.Sunburst` object. You're even welcome to use the HOOK STDOUT: [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), HOOK STDOUT: as we do below when we set `marker.colors` with `marker_colors`: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import numpy as np HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def average(values, weights): HOOK STDOUT: """Same as np.average, but remove nans""" HOOK STDOUT: total_obs = 0. HOOK STDOUT: total_weight = 0. HOOK STDOUT: if isinstance(values, np.float): HOOK STDOUT: values = [values] HOOK STDOUT: weights = [weights] HOOK STDOUT: for x, w in zip(values, weights): HOOK STDOUT: xw = x * w HOOK STDOUT: if np.isnan(xw): HOOK STDOUT: continue HOOK STDOUT: total_obs += xw HOOK STDOUT: total_weight += w HOOK STDOUT: return total_obs / total_weight if total_weight != 0 else np.NaN HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def life_expectancy(item): HOOK STDOUT: """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: sub = pop_and_exp.loc[item] if item else pop_and_exp HOOK STDOUT: return average(sub.life_expectancy, weights=sub.population) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: def text(item): HOOK STDOUT: """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" HOOK STDOUT: life_exp = life_expectancy(item) HOOK STDOUT: if life_exp > 0: HOOK STDOUT: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() HOOK STDOUT: return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: treemap = ep.Treemap(pop_and_exp.population, HOOK STDOUT: hoverinfo='label+text', HOOK STDOUT: text=text, HOOK STDOUT: root_label='World', HOOK STDOUT: # magic underscore notation HOOK STDOUT: marker_colors=life_expectancy, HOOK STDOUT: marker_colorscale='RdBu') HOOK STDOUT: HOOK STDOUT: go.Figure(treemap, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ## Sankey Plot HOOK STDOUT: HOOK STDOUT: Plot links from a dict, or a series with a source/target multiindex: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: Plot links from a DataFrame (sources as the index, targets as the columns): HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: import pandas as pd HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) HOOK STDOUT: go.Figure(ep.Sankey(links)) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: We conclude the examples with a plot in which the links are a list of pandas Series: HOOK STDOUT: HOOK STDOUT: ```python HOOK STDOUT: region_income = wb.get_countries().query("region != 'Aggregates'").copy() HOOK STDOUT: region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) HOOK STDOUT: income_lending = region_income.copy() HOOK STDOUT: region_income.set_index(['region', 'incomeLevel'], inplace=True) HOOK STDOUT: income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) HOOK STDOUT: HOOK STDOUT: layout = go.Layout(title='Regions income and lending type
Data from the World Bank') HOOK STDOUT: HOOK STDOUT: sankey = ep.Sankey( HOOK STDOUT: link_value=[region_income['population'], income_lending['population']], HOOK STDOUT: link_label=[region_income['name'], income_lending['name']]) HOOK STDOUT: HOOK STDOUT: go.Figure(sankey, layout) HOOK STDOUT: ``` HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: HOOK STDOUT: running dist_info HOOK STDOUT: writing easyplotly.egg-info/PKG-INFO HOOK STDOUT: writing dependency_links to easyplotly.egg-info/dependency_links.txt HOOK STDOUT: writing requirements to easyplotly.egg-info/requires.txt HOOK STDOUT: writing top-level names to easyplotly.egg-info/top_level.txt HOOK STDOUT: reading manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: adding license file 'LICENSE' HOOK STDOUT: writing manifest file 'easyplotly.egg-info/SOURCES.txt' HOOK STDOUT: creating '/builddir/build/BUILD/easyplotly-0.1.3/easyplotly.dist-info' HOOK STDOUT: adding license file "LICENSE" (matched pattern "LICEN[CS]E*") Handling pandas from wheel metadata: Requires-Dist Requirement satisfied: pandas (installed: pandas 1.3.3) Handling numpy from wheel metadata: Requires-Dist Requirement satisfied: numpy (installed: numpy 1.22.0) Handling plotly from wheel metadata: Requires-Dist Requirement satisfied: plotly (installed: plotly 4.14.3) + RPM_EC=0 ++ jobs -p + exit 0 Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.x1V6hw + umask 022 + cd /builddir/build/BUILD + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FCFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/easyplotly-0.1.3/.package_note-python-easyplotly-0.1.3-1.fc36.x86_64.ld' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + '[' -f /usr/lib/rpm/generate-rpm-note.sh ']' + /usr/lib/rpm/generate-rpm-note.sh python-easyplotly 0.1.3-1.fc36 x86_64 + cd easyplotly-0.1.3 + mkdir -p /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/easyplotly-0.1.3/.package_note-python-easyplotly-0.1.3-1.fc36.x86_64.ld' + TMPDIR=/builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir + /usr/bin/python3 -m pip wheel --wheel-dir /builddir/build/BUILD/easyplotly-0.1.3/pyproject-wheeldir --no-deps --use-pep517 --no-build-isolation --disable-pip-version-check --no-clean --progress-bar off --verbose . Processing /builddir/build/BUILD/easyplotly-0.1.3 Preparing metadata (pyproject.toml): started Running command /usr/bin/python3 /usr/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py prepare_metadata_for_build_wheel /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/tmp22vd8hyr # Easy Plotly [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) Star This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), especially ploting of hierarchical data, could be made easier. See the outputs of the commands below - tables and plots - in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. Or even, open this `README.md` as a notebook and run it interactively on [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! ## Installation Install the `easyplotly` python package with ``` pip install easyplotly ``` ## Sample data Our sample data is the population and life expectancy, per country and region: ```python import world_bank_data as wb import itables.interactive # Collect countries countries = wb.get_countries() region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) # Population & life expectancy region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) # Observations restricted to the countries pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() pop_and_exp ``` ## Sunburst Charts ```python import plotly.graph_objects as go import plotly.io as pio import easyplotly as ep pio.renderers.default = 'notebook_connected' layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) ``` Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` associates the corresponding label or value. ```python sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) go.Figure(sunburst, layout) ``` ## Treemaps The `Treemap` function works like the `Sunburst` one: ```python treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) go.Figure(treemap, layout) ``` Just like the `Sunburst` function, it also accepts all the arguments supported by the original `go.Sunburst` object. You're even welcome to use the [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), as we do below when we set `marker.colors` with `marker_colors`: ```python import numpy as np def average(values, weights): """Same as np.average, but remove nans""" total_obs = 0. total_weight = 0. if isinstance(values, np.float): values = [values] weights = [weights] for x, w in zip(values, weights): xw = x * w if np.isnan(xw): continue total_obs += xw total_weight += w return total_obs / total_weight if total_weight != 0 else np.NaN def life_expectancy(item): """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" sub = pop_and_exp.loc[item] if item else pop_and_exp return average(sub.life_expectancy, weights=sub.population) def text(item): """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" life_exp = life_expectancy(item) if life_exp > 0: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) treemap = ep.Treemap(pop_and_exp.population, hoverinfo='label+text', text=text, root_label='World', # magic underscore notation marker_colors=life_expectancy, marker_colorscale='RdBu') go.Figure(treemap, layout) ``` ## Sankey Plot Plot links from a dict, or a series with a source/target multiindex: ```python links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} go.Figure(ep.Sankey(links)) ``` Plot links from a DataFrame (sources as the index, targets as the columns): ```python import pandas as pd ``` ```python links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) go.Figure(ep.Sankey(links)) ``` We conclude the examples with a plot in which the links are a list of pandas Series: ```python region_income = wb.get_countries().query("region != 'Aggregates'").copy() region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) income_lending = region_income.copy() region_income.set_index(['region', 'incomeLevel'], inplace=True) income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) layout = go.Layout(title='Regions income and lending type
Data from the World Bank') sankey = ep.Sankey( link_value=[region_income['population'], income_lending['population']], link_label=[region_income['name'], income_lending['name']]) go.Figure(sankey, layout) ``` running dist_info creating /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info writing /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info/PKG-INFO writing dependency_links to /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info/dependency_links.txt writing requirements to /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info/requires.txt writing top-level names to /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info/top_level.txt writing manifest file '/builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info/SOURCES.txt' reading manifest file '/builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info/SOURCES.txt' adding license file 'LICENSE' writing manifest file '/builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.egg-info/SOURCES.txt' creating '/builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-modern-metadata-a7wchjmo/easyplotly.dist-info' adding license file "LICENSE" (matched pattern "LICEN[CS]E*") Preparing metadata (pyproject.toml): finished with status 'done' Building wheels for collected packages: easyplotly Building wheel for easyplotly (pyproject.toml): started Running command /usr/bin/python3 /usr/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py build_wheel /builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/tmp3mnj2er5 # Easy Plotly [![Build Status](https://travis-ci.com/mwouts/easyplotly.svg?branch=master)](https://travis-ci.com/mwouts/easyplotly) [![codecov.io](https://codecov.io/github/mwouts/easyplotly/coverage.svg?branch=master)](https://codecov.io/github/mwouts/easyplotly?branch=master) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/mwouts/easyplotly.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/mwouts/easyplotly/context:python) [![Pypi](https://img.shields.io/pypi/v/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) [![pyversions](https://img.shields.io/pypi/pyversions/easyplotly.svg)](https://pypi.python.org/pypi/easyplotly) [![Jupyter Notebook](https://img.shields.io/badge/Binder-Notebook-blue.svg)]( https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md) [![GitHub.io](https://img.shields.io/badge/GitHub-HTML-blue.svg)](https://mwouts.github.io/easyplotly) Star This is on-going research on how ploting with [Plotly.py](https://github.com/plotly/plotly.py), especially ploting of hierarchical data, could be made easier. See the outputs of the commands below - tables and plots - in the [HTML export](https://mwouts.github.io/easyplotly/) of this notebook. Or even, open this `README.md` as a notebook and run it interactively on [Binder](https://mybinder.org/v2/gh/mwouts/easyplotly/master?filepath=README.md)! ## Installation Install the `easyplotly` python package with ``` pip install easyplotly ``` ## Sample data Our sample data is the population and life expectancy, per country and region: ```python import world_bank_data as wb import itables.interactive # Collect countries countries = wb.get_countries() region_country = countries[['region', 'name']].rename(columns={'name': 'country'}) # Population & life expectancy region_country['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) region_country['life_expectancy'] = wb.get_series('SP.DYN.LE00.IN', mrv=1, id_or_value='id', simplify_index=True) # Observations restricted to the countries pop_and_exp = region_country.loc[countries.region != 'Aggregates'].set_index(['region', 'country']).sort_index() pop_and_exp ``` ## Sunburst Charts ```python import plotly.graph_objects as go import plotly.io as pio import easyplotly as ep pio.renderers.default = 'notebook_connected' layout = go.Layout(title='World Population and Life Expectancy
Data from the World Bank', height=800) ``` Our `Sunburst` function accepts inputs of many types: pandas Series, dictionaries, and list of such objects. If you want, you can redefine `labels`, or add other arguments like `text` - use either a Series with an index identical to that of `values`, or a function that to any tuple `(level0, level1, ... leveln)` associates the corresponding label or value. ```python sunburst = ep.Sunburst(pop_and_exp.population, text=pop_and_exp.life_expectancy) go.Figure(sunburst, layout) ``` ## Treemaps The `Treemap` function works like the `Sunburst` one: ```python treemap = ep.Treemap(pop_and_exp.population, text=pop_and_exp.life_expectancy) go.Figure(treemap, layout) ``` Just like the `Sunburst` function, it also accepts all the arguments supported by the original `go.Sunburst` object. You're even welcome to use the [magic underscore notation](https://plot.ly/python/creating-and-updating-figures/#magic-underscore-notation), as we do below when we set `marker.colors` with `marker_colors`: ```python import numpy as np def average(values, weights): """Same as np.average, but remove nans""" total_obs = 0. total_weight = 0. if isinstance(values, np.float): values = [values] weights = [weights] for x, w in zip(values, weights): xw = x * w if np.isnan(xw): continue total_obs += xw total_weight += w return total_obs / total_weight if total_weight != 0 else np.NaN def life_expectancy(item): """Life expectancy associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" sub = pop_and_exp.loc[item] if item else pop_and_exp return average(sub.life_expectancy, weights=sub.population) def text(item): """Return the text associated to a tuple like (), ('Europe & Central Asia') or ('East Asia & Pacific', 'China')""" life_exp = life_expectancy(item) if life_exp > 0: pop = pop_and_exp.population.loc[item].sum() if item else pop_and_exp.population.sum() return 'Population: {:,}
Life expectancy: {:.2f}'.format(int(pop), life_exp) treemap = ep.Treemap(pop_and_exp.population, hoverinfo='label+text', text=text, root_label='World', # magic underscore notation marker_colors=life_expectancy, marker_colorscale='RdBu') go.Figure(treemap, layout) ``` ## Sankey Plot Plot links from a dict, or a series with a source/target multiindex: ```python links = {('A', 'B'): 3, ('B', 'C'): 1, ('B', 'D'): 2, ('C', 'A'): 1, ('D', 'A'): 1, ('A', 'D'): 1} go.Figure(ep.Sankey(links)) ``` Plot links from a DataFrame (sources as the index, targets as the columns): ```python import pandas as pd ``` ```python links = pd.DataFrame(1, index=['Source A', 'Source B'], columns=['Target']) go.Figure(ep.Sankey(links)) ``` We conclude the examples with a plot in which the links are a list of pandas Series: ```python region_income = wb.get_countries().query("region != 'Aggregates'").copy() region_income['population'] = wb.get_series('SP.POP.TOTL', mrv=1, id_or_value='id', simplify_index=True) income_lending = region_income.copy() region_income.set_index(['region', 'incomeLevel'], inplace=True) income_lending.set_index(['incomeLevel', 'lendingType'], inplace=True) layout = go.Layout(title='Regions income and lending type
Data from the World Bank') sankey = ep.Sankey( link_value=[region_income['population'], income_lending['population']], link_label=[region_income['name'], income_lending['name']]) go.Figure(sankey, layout) ``` running bdist_wheel running build running build_py creating build creating build/lib creating build/lib/easyplotly copying easyplotly/version.py -> build/lib/easyplotly copying easyplotly/treemap.py -> build/lib/easyplotly copying easyplotly/sunburst.py -> build/lib/easyplotly copying easyplotly/sankey.py -> build/lib/easyplotly copying easyplotly/internals.py -> build/lib/easyplotly copying easyplotly/__init__.py -> build/lib/easyplotly installing to build/bdist.linux-x86_64/wheel running install running install_lib creating build/bdist.linux-x86_64 creating build/bdist.linux-x86_64/wheel creating build/bdist.linux-x86_64/wheel/easyplotly copying build/lib/easyplotly/__init__.py -> build/bdist.linux-x86_64/wheel/easyplotly copying build/lib/easyplotly/internals.py -> build/bdist.linux-x86_64/wheel/easyplotly copying build/lib/easyplotly/sankey.py -> build/bdist.linux-x86_64/wheel/easyplotly copying build/lib/easyplotly/sunburst.py -> build/bdist.linux-x86_64/wheel/easyplotly copying build/lib/easyplotly/treemap.py -> build/bdist.linux-x86_64/wheel/easyplotly copying build/lib/easyplotly/version.py -> build/bdist.linux-x86_64/wheel/easyplotly running install_egg_info running egg_info creating easyplotly.egg-info writing easyplotly.egg-info/PKG-INFO writing dependency_links to easyplotly.egg-info/dependency_links.txt writing requirements to easyplotly.egg-info/requires.txt writing top-level names to easyplotly.egg-info/top_level.txt writing manifest file 'easyplotly.egg-info/SOURCES.txt' reading manifest file 'easyplotly.egg-info/SOURCES.txt' adding license file 'LICENSE' writing manifest file 'easyplotly.egg-info/SOURCES.txt' Copying easyplotly.egg-info to build/bdist.linux-x86_64/wheel/easyplotly-0.1.3-py3.10.egg-info running install_scripts adding license file "LICENSE" (matched pattern "LICEN[CS]E*") creating build/bdist.linux-x86_64/wheel/easyplotly-0.1.3.dist-info/WHEEL creating '/builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir/pip-wheel-aucizprn/tmpltu8dh29/easyplotly-0.1.3-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it adding 'easyplotly/__init__.py' adding 'easyplotly/internals.py' adding 'easyplotly/sankey.py' adding 'easyplotly/sunburst.py' adding 'easyplotly/treemap.py' adding 'easyplotly/version.py' adding 'easyplotly-0.1.3.dist-info/LICENSE' adding 'easyplotly-0.1.3.dist-info/METADATA' adding 'easyplotly-0.1.3.dist-info/WHEEL' adding 'easyplotly-0.1.3.dist-info/top_level.txt' adding 'easyplotly-0.1.3.dist-info/RECORD' removing build/bdist.linux-x86_64/wheel Building wheel for easyplotly (pyproject.toml): finished with status 'done' Created wheel for easyplotly: filename=easyplotly-0.1.3-py3-none-any.whl size=8707 sha256=1619cb8d16aea354952a8a5a47db95c5762790748f00055b7028536ae06eb6f4 Stored in directory: /builddir/.cache/pip/wheels/0f/2e/9c/5455d35f81e49982f238ca357e836b2160f81c24c485d95251 Successfully built easyplotly + RPM_EC=0 ++ jobs -p + exit 0 Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.1VJEeb + umask 022 + cd /builddir/build/BUILD + '[' /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 '!=' / ']' + rm -rf /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 ++ dirname /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 + mkdir -p /builddir/build/BUILDROOT + mkdir /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FCFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/easyplotly-0.1.3/.package_note-python-easyplotly-0.1.3-1.fc36.x86_64.ld' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd easyplotly-0.1.3 ++ xargs basename --multiple ++ sed -E 's/([^-]+)-([^-]+)-.+\.whl/\1==\2/' ++ ls /builddir/build/BUILD/easyplotly-0.1.3/pyproject-wheeldir/easyplotly-0.1.3-py3-none-any.whl + specifier=easyplotly==0.1.3 + TMPDIR=/builddir/build/BUILD/easyplotly-0.1.3/.pyproject-builddir + /usr/bin/python3 -m pip install --root /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 --no-deps --disable-pip-version-check --progress-bar off --verbose --ignore-installed --no-warn-script-location --no-index --no-cache-dir --find-links /builddir/build/BUILD/easyplotly-0.1.3/pyproject-wheeldir easyplotly==0.1.3 Using pip 21.3.1 from /usr/lib/python3.10/site-packages/pip (python 3.10) Looking in links: /builddir/build/BUILD/easyplotly-0.1.3/pyproject-wheeldir Processing ./pyproject-wheeldir/easyplotly-0.1.3-py3-none-any.whl Installing collected packages: easyplotly Successfully installed easyplotly-0.1.3 + '[' -d /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/bin ']' + rm -f /builddir/build/BUILD/pyproject-ghost-distinfo + site_dirs=() + '[' -d /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages ']' + site_dirs+=("/usr/lib/python3.10/site-packages") + '[' /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib64/python3.10/site-packages '!=' /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages ']' + '[' -d /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib64/python3.10/site-packages ']' + for site_dir in ${site_dirs[@]} + for distinfo in /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64$site_dir/*.dist-info + echo '%ghost /usr/lib/python3.10/site-packages/easyplotly-0.1.3.dist-info' + sed -i s/pip/rpm/ /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages/easyplotly-0.1.3.dist-info/INSTALLER + PYTHONPATH=/usr/lib/rpm/redhat + /usr/bin/python3 -B /usr/lib/rpm/redhat/pyproject_preprocess_record.py --buildroot /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 --record /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages/easyplotly-0.1.3.dist-info/RECORD --output /builddir/build/BUILD/pyproject-record + rm -fv /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages/easyplotly-0.1.3.dist-info/RECORD removed '/builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages/easyplotly-0.1.3.dist-info/RECORD' + rm -fv /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages/easyplotly-0.1.3.dist-info/REQUESTED removed '/builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages/easyplotly-0.1.3.dist-info/REQUESTED' ++ wc -l /builddir/build/BUILD/pyproject-ghost-distinfo ++ cut -f1 '-d ' + lines=1 + '[' 1 -ne 1 ']' + /usr/bin/python3 /usr/lib/rpm/redhat/pyproject_save_files.py --output-files /builddir/build/BUILD/pyproject-files --output-modules /builddir/build/BUILD/pyproject-modules --buildroot /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 --sitelib /usr/lib/python3.10/site-packages --sitearch /usr/lib64/python3.10/site-packages --python-version 3.10 --pyproject-record /builddir/build/BUILD/pyproject-record --prefix /usr '*' +auto + /usr/bin/find-debuginfo -j2 --strict-build-id -m -i --build-id-seed 0.1.3-1.fc36 --unique-debug-suffix -0.1.3-1.fc36.x86_64 --unique-debug-src-base python-easyplotly-0.1.3-1.fc36.x86_64 --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 -S debugsourcefiles.list /builddir/build/BUILD/easyplotly-0.1.3 find: 'debug': No such file or directory + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-ldconfig + /usr/lib/rpm/brp-compress + /usr/lib/rpm/redhat/brp-strip-lto /usr/bin/strip + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip + /usr/lib/rpm/check-rpaths + /usr/lib/rpm/redhat/brp-mangle-shebangs + /usr/lib/rpm/redhat/brp-python-bytecompile '' 1 0 Bytecompiling .py files below /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10 using python3.10 + /usr/lib/rpm/redhat/brp-python-hardlink Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.uV0Gz0 + umask 022 + cd /builddir/build/BUILD + CFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CFLAGS + CXXFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' + export CXXFLAGS + FFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FFLAGS + FCFLAGS='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -I/usr/lib64/gfortran/modules' + export FCFLAGS + LDFLAGS='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-dT,/builddir/build/BUILD/easyplotly-0.1.3/.package_note-python-easyplotly-0.1.3-1.fc36.x86_64.ld' + export LDFLAGS + LT_SYS_LIBRARY_PATH=/usr/lib64: + export LT_SYS_LIBRARY_PATH + CC=gcc + export CC + CXX=g++ + export CXX + cd easyplotly-0.1.3 + '[' '!' -f /builddir/build/BUILD/pyproject-modules ']' + PATH=/builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/bin:/builddir/.local/bin:/builddir/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin + PYTHONPATH=/builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib64/python3.10/site-packages:/builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages + _PYTHONSITE=/builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib64/python3.10/site-packages:/builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64/usr/lib/python3.10/site-packages + PYTHONDONTWRITEBYTECODE=1 + /usr/bin/python3 -s /usr/lib/rpm/redhat/import_all_modules.py -f /builddir/build/BUILD/pyproject-modules -t Check import: easyplotly + RPM_EC=0 ++ jobs -p + exit 0 Processing files: python3-easyplotly-0.1.3-1.fc36.noarch Provides: python-easyplotly = 0.1.3-1.fc36 python3-easyplotly = 0.1.3-1.fc36 python3.10-easyplotly = 0.1.3-1.fc36 python3.10dist(easyplotly) = 0.1.3 python3dist(easyplotly) = 0.1.3 Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PartialHardlinkSets) <= 4.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires: python(abi) = 3.10 python3.10dist(numpy) python3.10dist(pandas) python3.10dist(plotly) Checking for unpackaged file(s): /usr/lib/rpm/check-files /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 Wrote: /builddir/build/SRPMS/python-easyplotly-0.1.3-1.fc36.src.rpm Wrote: /builddir/build/RPMS/python3-easyplotly-0.1.3-1.fc36.noarch.rpm Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.X3Clf5 + umask 022 + cd /builddir/build/BUILD + cd easyplotly-0.1.3 + /usr/bin/rm -rf /builddir/build/BUILDROOT/python-easyplotly-0.1.3-1.fc36.x86_64 + RPM_EC=0 ++ jobs -p + exit 0 Child return code was: 0