├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── imgs ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png ├── pycoolplot ├── CHANGELOG.md ├── VERSION ├── __init__.py ├── bump-version.sh └── pycoolplot.py ├── sample.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | .DS_Store 6 | 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | .hypothesis/ 50 | .pytest_cache/ 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | db.sqlite3 60 | 61 | # Flask stuff: 62 | instance/ 63 | .webassets-cache 64 | 65 | # Scrapy stuff: 66 | .scrapy 67 | 68 | # Sphinx documentation 69 | docs/_build/ 70 | 71 | # PyBuilder 72 | target/ 73 | 74 | # Jupyter Notebook 75 | .ipynb_checkpoints 76 | 77 | # pyenv 78 | .python-version 79 | 80 | # celery beat schedule file 81 | celerybeat-schedule 82 | 83 | # SageMath parsed files 84 | *.sage.py 85 | 86 | # Environments 87 | .env 88 | .venv 89 | env/ 90 | venv/ 91 | ENV/ 92 | env.bak/ 93 | venv.bak/ 94 | 95 | # Spyder project settings 96 | .spyderproject 97 | .spyproject 98 | 99 | # Rope project settings 100 | .ropeproject 101 | 102 | # mkdocs documentation 103 | /site 104 | 105 | # mypy 106 | .mypy_cache/ 107 | /.idea/ 108 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Atsushi Sakai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include pycoolplot/VERSION 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyCoolPlot 2 | 3 | A cool plotting module in Python 4 | 5 | # What is this? 6 | 7 | This is a plotting module in Python. 8 | 9 | Ref: 10 | 11 | - [データ視覚化のデザイン \#1|Go Ando / THE GUILD|note](https://note.mu/goando/n/neb6ea35f1da3) 12 | 13 | - [「データ視覚化のデザイン \#1」をmatplotlibで実装する \- Qiita](https://qiita.com/skotaro/items/cdb0732ad1ad2a4b6236) 14 | 15 | # Requirements 16 | 17 | - Python 3.6.x or higher 18 | 19 | - matplotlib 20 | 21 | - numpy 22 | 23 | - pandas 24 | 25 | 26 | # Download 27 | 28 | ## Using pip 29 | 30 | >$ pip install PyCoolPlot 31 | 32 | PyPI page: 33 | 34 | - [PyCoolPlot · PyPI](https://pypi.org/project/PyCoolPlot/#description) 35 | 36 | 37 | ## Manual install 38 | 39 | 1. Install Python 3.6.x. 40 | 41 | 2. Clone or download as zip this repository. 42 | 43 | 3. import pycoolplot.py 44 | 45 | # How to use 46 | 47 | The sample code might be helpful: 48 | 49 | - [PyCoolPlot/sample\.py](https://github.com/AtsushiSakai/PyCoolPlot/blob/master/sample.py) 50 | 51 | ## import 52 | 53 | If you use pip to install PyCoolPlot, you can import it like: 54 | 55 | from pycoolplot import pycoolplot 56 | 57 | 58 | ## Horizontal bar plot 59 | 60 | You can plot a beautiful horizontal bar plot like: 61 | 62 | data = [1000, 2000, 10000] 63 | index = ["A", "B", "C"] 64 | pycoolplot.horizontal_bar(index, data) 65 | pycoolplot.plt.show() 66 | 67 | You will see: 68 | 69 | ![1](https://github.com/AtsushiSakai/PyCoolPlot/raw/master/imgs/1.png) 70 | 71 | If you want a rate bar plot, you can set rate\_graph is True like: 72 | 73 | data = [1000, 2000, 10000] 74 | index = ["A", "B", "C"] 75 | pycoolplot.horizontal_bar(index, data, rate_graph=True) 76 | pycoolplot.plt.show() 77 | 78 | 79 | You will see: 80 | 81 | ![2](https://github.com/AtsushiSakai/PyCoolPlot/raw/master/imgs/2.png) 82 | 83 | ## Line graph 84 | 85 | You can plot a beautiful line graph like: 86 | 87 | data2 = [[970, 1010, 1015, 1008], 88 | [975, 1020, 1002, 1035], 89 | [975, 985, 995, 999]] 90 | index2 = ['Toyota', 'VW', 'GM'] 91 | columns = [2013, 2014, 2015, 2016] 92 | ylabel = "Number" 93 | xlabel = "Year" 94 | pycoolplot.line_graph(data2, index2, columns, xlabel, 95 | ylabel, xtick=1, ytick=25) 96 | pycoolplot.plt.show() 97 | 98 | You can get: 99 | 100 | ![3](https://github.com/AtsushiSakai/PyCoolPlot/raw/master/imgs/3.png) 101 | 102 | If you want to focus a line, you can set focus\_id like: 103 | 104 | data2 = [[970, 1010, 1015, 1008], 105 | [975, 1020, 1002, 1035], 106 | [975, 985, 995, 999]] 107 | index2 = ['Toyota', 'VW', 'GM'] 108 | columns = [2013, 2014, 2015, 2016] 109 | ylabel = "Number" 110 | xlabel = "Year" 111 | focus_id = 1 # the index of focusing line, in this case Toyota=0, VW=1, GM=2 112 | pycoolplot.line_graph(data2, index2, columns, xlabel, 113 | ylabel, xtick=1, ytick=25, focus_id=focus_id) 114 | pycoolplot.plt.show() 115 | 116 | ![4](https://github.com/AtsushiSakai/PyCoolPlot/raw/master/imgs/4.png) 117 | 118 | ## Time bar chart 119 | 120 | You can plot a beautiful time series bar chart like: 121 | 122 | data = pycoolplot.np.linspace(450, 990, 12) + \ 123 | pycoolplot.np.random.randint(-50, 50, 12) 124 | time_index = pycoolplot.pd.date_range('2017/5', periods=12, freq='MS') 125 | pycoolplot.time_vertical_bar(data, time_index, xlabel="time", ylabel="MAU") 126 | pycoolplot.plt.show() 127 | 128 | ![5](https://github.com/AtsushiSakai/PyCoolPlot/raw/master/imgs/5.png) 129 | 130 | # License 131 | 132 | MIT 133 | 134 | # Author 135 | 136 | - [Atsushi Sakai](https://github.com/AtsushiSakai/) ([@Atsushi_twi](https://twitter.com/Atsushi_twi)) 137 | 138 | 139 | -------------------------------------------------------------------------------- /imgs/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AtsushiSakai/PyCoolPlot/da4c9d1cffcefba59b9e57e17202cf0016c46f73/imgs/1.png -------------------------------------------------------------------------------- /imgs/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AtsushiSakai/PyCoolPlot/da4c9d1cffcefba59b9e57e17202cf0016c46f73/imgs/2.png -------------------------------------------------------------------------------- /imgs/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AtsushiSakai/PyCoolPlot/da4c9d1cffcefba59b9e57e17202cf0016c46f73/imgs/3.png -------------------------------------------------------------------------------- /imgs/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AtsushiSakai/PyCoolPlot/da4c9d1cffcefba59b9e57e17202cf0016c46f73/imgs/4.png -------------------------------------------------------------------------------- /imgs/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AtsushiSakai/PyCoolPlot/da4c9d1cffcefba59b9e57e17202cf0016c46f73/imgs/5.png -------------------------------------------------------------------------------- /pycoolplot/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 (August 21, 2022) 2 | - Initial release 3 | 4 | -------------------------------------------------------------------------------- /pycoolplot/VERSION: -------------------------------------------------------------------------------- 1 | 0.1.0 2 | -------------------------------------------------------------------------------- /pycoolplot/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AtsushiSakai/PyCoolPlot/da4c9d1cffcefba59b9e57e17202cf0016c46f73/pycoolplot/__init__.py -------------------------------------------------------------------------------- /pycoolplot/bump-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # works with a file called VERSION in the current directory, 4 | # the contents of which should be a semantic version number 5 | # such as "1.2.3" or even "1.2.3-beta+001.ab" 6 | 7 | # this script will display the current version, automatically 8 | # suggest a "minor" version update, and ask for input to use 9 | # the suggestion, or a newly entered value. 10 | 11 | # once the new version number is determined, the script will 12 | # pull a list of changes from git history, prepend this to 13 | # a file called CHANGELOG.md (under the title of the new version 14 | # number), give user a chance to review and update the changelist 15 | # manually if needed and create a GIT tag. 16 | 17 | NOW="$(date +'%B %d, %Y')" 18 | RED="\033[1;31m" 19 | GREEN="\033[0;32m" 20 | YELLOW="\033[1;33m" 21 | BLUE="\033[1;34m" 22 | PURPLE="\033[1;35m" 23 | CYAN="\033[1;36m" 24 | WHITE="\033[1;37m" 25 | RESET="\033[0m" 26 | 27 | LATEST_HASH=`git log --pretty=format:'%h' -n 1` 28 | 29 | QUESTION_FLAG="${GREEN}?" 30 | WARNING_FLAG="${YELLOW}!" 31 | NOTICE_FLAG="${CYAN}❯" 32 | 33 | ADJUSTMENTS_MSG="${QUESTION_FLAG} ${CYAN}Now you can make adjustments to ${WHITE}CHANGELOG.md${CYAN}. Then press enter to continue." 34 | PUSHING_MSG="${NOTICE_FLAG} Pushing new version to the ${WHITE}origin${CYAN}..." 35 | 36 | if [ -f VERSION ]; then 37 | BASE_STRING=`cat VERSION` 38 | BASE_LIST=(`echo $BASE_STRING | tr '.' ' '`) 39 | V_MAJOR=${BASE_LIST[0]} 40 | V_MINOR=${BASE_LIST[1]} 41 | V_PATCH=${BASE_LIST[2]} 42 | echo -e "${NOTICE_FLAG} Current version: ${WHITE}$BASE_STRING" 43 | echo -e "${NOTICE_FLAG} Latest commit hash: ${WHITE}$LATEST_HASH" 44 | V_MINOR=$((V_MINOR + 1)) 45 | V_PATCH=0 46 | SUGGESTED_VERSION="$V_MAJOR.$V_MINOR.$V_PATCH" 47 | echo -ne "${QUESTION_FLAG} ${CYAN}Enter a version number [${WHITE}$SUGGESTED_VERSION${CYAN}]: " 48 | read INPUT_STRING 49 | if [ "$INPUT_STRING" = "" ]; then 50 | INPUT_STRING=$SUGGESTED_VERSION 51 | fi 52 | echo -e "${NOTICE_FLAG} Will set new version to be ${WHITE}$INPUT_STRING" 53 | echo $INPUT_STRING > VERSION 54 | echo "## $INPUT_STRING ($NOW)" > tmpfile 55 | git log --pretty=format:" - %s" "v$BASE_STRING"...HEAD >> tmpfile 56 | echo "" >> tmpfile 57 | echo "" >> tmpfile 58 | cat CHANGELOG.md >> tmpfile 59 | mv tmpfile CHANGELOG.md 60 | echo -e "$ADJUSTMENTS_MSG" 61 | read 62 | echo -e "$PUSHING_MSG" 63 | git add CHANGELOG.md VERSION 64 | git commit -m "Bump version to ${INPUT_STRING}." 65 | git tag -a -m "Tag version ${INPUT_STRING}." "v$INPUT_STRING" 66 | git push origin --tags 67 | else 68 | echo -e "${WARNING_FLAG} Could not find a VERSION file." 69 | echo -ne "${QUESTION_FLAG} ${CYAN}Do you want to create a version file and start from scratch? [${WHITE}y${CYAN}]: " 70 | read RESPONSE 71 | if [ "$RESPONSE" = "" ]; then RESPONSE="y"; fi 72 | if [ "$RESPONSE" = "Y" ]; then RESPONSE="y"; fi 73 | if [ "$RESPONSE" = "Yes" ]; then RESPONSE="y"; fi 74 | if [ "$RESPONSE" = "yes" ]; then RESPONSE="y"; fi 75 | if [ "$RESPONSE" = "YES" ]; then RESPONSE="y"; fi 76 | if [ "$RESPONSE" = "y" ]; then 77 | echo "0.1.0" > VERSION 78 | echo "## 0.1.0 ($NOW)" > CHANGELOG.md 79 | git log --pretty=format:" - %s" >> CHANGELOG.md 80 | echo "" >> CHANGELOG.md 81 | echo "" >> CHANGELOG.md 82 | echo -e "$ADJUSTMENTS_MSG" 83 | read 84 | echo -e "$PUSHING_MSG" 85 | git add VERSION CHANGELOG.md 86 | git commit -m "Add VERSION and CHANGELOG.md files, Bump version to v0.1.0." 87 | git tag -a -m "Tag version 0.1.0." "v0.1.0" 88 | git push origin --tags 89 | fi 90 | fi 91 | 92 | echo -e "${NOTICE_FLAG} Finished." -------------------------------------------------------------------------------- /pycoolplot/pycoolplot.py: -------------------------------------------------------------------------------- 1 | """ 2 | Cool plot library for Python 3 | 4 | author: Atsushi Sakai (@Atsushi_twi) 5 | 6 | Inspired: 7 | - https://note.mu/goando/n/neb6ea35f1da3 8 | - Qiita https://qiita.com/skotaro/items/cdb0732ad1ad2a4b6236 9 | 10 | """ 11 | 12 | import matplotlib 13 | import matplotlib.pyplot as plt 14 | import numpy as np 15 | import pandas as pd 16 | from matplotlib.ticker import MultipleLocator 17 | import matplotlib.dates as mdates 18 | import os 19 | 20 | 21 | def horizontal_bar(index, data, color="C0", xlabel="", rate_graph=False): 22 | """ 23 | Beautiful bar chart 24 | 25 | usage: 26 | data = [1000, 2000, 10000] 27 | index = ["A", "B", "C"] 28 | horizontal_bar(index, data) 29 | plt.show() 30 | 31 | """ 32 | 33 | if rate_graph: 34 | data = [round(d / sum(data) * 100.0, 1) for d in data] 35 | 36 | combatpower = pd.DataFrame(data, 37 | index=index, 38 | columns=['data']) 39 | 40 | fig, ax = plt.subplots() 41 | plt.gca().invert_yaxis() 42 | ax.invert_yaxis() 43 | [spine.set_visible(False) for spine in ax.spines.values()] 44 | ax.tick_params(bottom=False, left=False, labelbottom=False) 45 | ax.tick_params(axis='y', labelsize='x-large') 46 | vmax = combatpower['data'].max() 47 | low_contrast(xlabel, "", ax) 48 | combatpower.plot.barh(legend=False, ax=ax, width=0.8, color=color) 49 | for i, value in enumerate(combatpower['data']): 50 | if rate_graph: 51 | ax.text(value + vmax * 0.02, i, 52 | f'{value:,}%', fontsize='x-large', color=color) 53 | else: 54 | ax.text(value + vmax * 0.02, i, 55 | f'{value:,}', fontsize='x-large', color=color) 56 | 57 | plt.grid(False) 58 | 59 | 60 | def line_graph(data, index, columns, xlabel, ylabel, 61 | xtick=None, ytick=None, focus_id=None, 62 | focus_color='limegreen'): 63 | """ 64 | Beautiful line graph 65 | 66 | usage: 67 | data = [[970, 1010, 1015, 1008], 68 | [975, 1020, 1002, 1035], 69 | [975, 985, 995, 999]] 70 | index = ['Toyota', 'VW', 'GM'] 71 | columns = [2013, 2014, 2015, 2016] 72 | ylabel = "Number" 73 | xlabel = "Year" 74 | line_graph(data, index, columns, xlabel, 75 | ylabel, xtick=1, ytick=25, focus_id=None) 76 | plt.show() 77 | 78 | """ 79 | carsales = pd.DataFrame(data, 80 | index=index, 81 | columns=columns) 82 | 83 | fig, ax = plt.subplots() 84 | if focus_id is None: 85 | carsales.T.plot(ax=ax, linewidth=4, legend=False) 86 | else: 87 | carsales.T.plot(ax=ax, linewidth=4, legend=False, color="lightgray") 88 | ax.lines[focus_id].set_color(focus_color) 89 | year = carsales.columns.values 90 | ax.set(xlabel=xlabel, ylabel=ylabel, xlim=(year.min(), year.max())) 91 | # adjust tick 92 | if xtick is not None: 93 | ax.xaxis.set_major_locator(MultipleLocator(xtick)) 94 | if ytick is not None: 95 | ax.yaxis.set_major_locator(MultipleLocator(ytick)) 96 | 97 | ax.grid(axis='x') 98 | 99 | ax.tick_params(bottom=False, left=False) 100 | 101 | ax.spines['right'].set_visible(False) 102 | ax.spines['left'].set_visible(False) 103 | ax.spines['top'].set_visible(False) 104 | 105 | low_contrast(xlabel, ylabel, ax) 106 | 107 | for i, name in enumerate(carsales.index.values): 108 | if focus_id is None: 109 | c, f = f'C{i}', 'large' 110 | else: 111 | if i == focus_id: 112 | c, f = focus_color, 'x-large' 113 | else: 114 | c, f = 'gray', 'large' 115 | 116 | ax.text(year.max() + 0.03, ax.lines[i].get_data()[1][-1], name, 117 | color=c, fontsize=f, va='center') 118 | 119 | 120 | def time_vertical_bar(data, time_index, 121 | xtick=None, ytick=None, xlabel="", ylabel=""): 122 | """ 123 | Beautiful time vertical bar 124 | 125 | usage: 126 | data = np.linspace(450, 990, 12) + np.random.randint(-50, 50, 12) 127 | time_index = pd.date_range('2017/5', periods=12, freq='MS') 128 | time_vertical_bar(data, time_index, xlabel="time", ylabel="MAU") 129 | plt.show() 130 | 131 | """ 132 | 133 | df = pd.Series(data, index=time_index, name=ylabel) 134 | 135 | fig, ax = plt.subplots() 136 | plt.grid(False) 137 | 138 | ax.bar(df.index, df, width=20, 139 | color='coral', zorder=2, align='center') 140 | if xtick is not None: 141 | ax.xaxis.set_major_locator(MultipleLocator(xtick)) 142 | if ytick is not None: 143 | ax.yaxis.set_major_locator(MultipleLocator(ytick)) 144 | 145 | ax.tick_params(bottom=False, left=False) 146 | 147 | ax.grid(axis='y') 148 | low_contrast(xlabel, ylabel, ax) 149 | ax.spines['left'].set_visible(False) 150 | ax.spines['right'].set_visible(False) 151 | ax.spines['top'].set_visible(False) 152 | if os.name == "nt": #windows 153 | ax.xaxis.set_major_formatter(mdates.DateFormatter('%m')) 154 | else: # other 155 | ax.xaxis.set_major_formatter(mdates.DateFormatter('%-m')) 156 | ax.xaxis.set_major_locator(mdates.MonthLocator()) 157 | fig.canvas.draw() 158 | for key, gr in df.groupby(df.index.year): 159 | i = np.where(df.index == gr.index[0])[0][0] 160 | pos = ax.get_xmajorticklabels()[i].get_position() 161 | ax.annotate(f' {key}', xy=(pos[0] - 15, 0), xycoords='data', 162 | xytext=(0, -30), textcoords='offset points', color='dimgray', 163 | ha='center', va='bottom', 164 | arrowprops={'arrowstyle': '-', 'color': 'dimgray'}) 165 | 166 | 167 | def low_contrast(xlabel, ylabel, ax): 168 | ax.set_ylabel(ylabel, color='gray') 169 | ax.set_xlabel(xlabel, color='gray') 170 | ax.tick_params(axis='x', colors='gray') 171 | ax.tick_params(axis='y', colors='gray') 172 | ax.spines['left'].set_color('dimgray') 173 | ax.spines['right'].set_color('dimgray') 174 | ax.spines['top'].set_color('dimgray') 175 | ax.spines['bottom'].set_color('dimgray') 176 | 177 | 178 | def main(): 179 | print(__file__ + " start!!") 180 | print("matplolib version:", matplotlib._version.get_versions()['version']) 181 | 182 | data = [1000, 2000, 10000] 183 | index = ["A", "B", "C"] 184 | horizontal_bar(index, data, rate_graph=False) 185 | 186 | data2 = [[970, 1010, 1015, 1008], 187 | [975, 1020, 1002, 1035], 188 | [975, 985, 995, 999]] 189 | index2 = ['Toyota', 'VW', 'GM'] 190 | columns = [2013, 2014, 2015, 2016] 191 | ylabel = "Number" 192 | xlabel = "Year" 193 | line_graph(data2, index2, columns, xlabel, 194 | ylabel, xtick=1, ytick=25, focus_id=None) 195 | 196 | data = np.linspace(450, 990, 12) + np.random.randint(-50, 50, 12) 197 | time_index = pd.date_range('2017/5', periods=12, freq='MS') 198 | time_vertical_bar(data, time_index, xlabel="time", ylabel="MAU") 199 | 200 | plt.show() 201 | 202 | 203 | if __name__ == '__main__': 204 | main() 205 | -------------------------------------------------------------------------------- /sample.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | Sample code for PyCoolPlot 4 | 5 | author: Atsushi Sakai (@Atsushi_twi) 6 | 7 | """ 8 | from pycoolplot import pycoolplot 9 | 10 | 11 | # Horizontal bar plot 12 | data = [1000, 2000, 10000] 13 | index = ["A", "B", "C"] 14 | pycoolplot.horizontal_bar(index, data) 15 | 16 | # Horizontal rate bar plot 17 | data = [1000, 2000, 10000] 18 | index = ["A", "B", "C"] 19 | pycoolplot.horizontal_bar(index, data, rate_graph=True) 20 | 21 | 22 | # Line graph 23 | data2 = [[970, 1010, 1015, 1008], 24 | [975, 1020, 1002, 1035], 25 | [975, 985, 995, 999]] 26 | index2 = ['Toyota', 'VW', 'GM'] 27 | columns = [2013, 2014, 2015, 2016] 28 | ylabel = "Number" 29 | xlabel = "Year" 30 | pycoolplot.line_graph(data2, index2, columns, xlabel, 31 | ylabel, xtick=1, ytick=25) 32 | 33 | # Line graph with focusing a line 34 | data2 = [[970, 1010, 1015, 1008], 35 | [975, 1020, 1002, 1035], 36 | [975, 985, 995, 999]] 37 | index2 = ['Toyota', 'VW', 'GM'] 38 | columns = [2013, 2014, 2015, 2016] 39 | ylabel = "Number" 40 | xlabel = "Year" 41 | focus_id = 1 # the index of focusing line, in this case Toyota=0, VW=1, GM=2 42 | pycoolplot.line_graph(data2, index2, columns, xlabel, 43 | ylabel, xtick=1, ytick=25, focus_id=focus_id) 44 | 45 | # Time series vertical bar plot 46 | data = pycoolplot.np.linspace(450, 990, 12) + \ 47 | pycoolplot.np.random.randint(-50, 50, 12) 48 | time_index = pycoolplot.pd.date_range('2017/5', periods=12, freq='MS') 49 | pycoolplot.time_vertical_bar(data, time_index, xlabel="time", ylabel="MAU") 50 | 51 | 52 | pycoolplot.plt.show() 53 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | Setup script for PyCoolPlot 3 | 4 | How to upload new release 5 | 6 | 1. run bum-version.sh 7 | 8 | 2. setup twine, see:https://blog.amedama.jp/entry/2017/12/31/175036 9 | 10 | 3. create zip file: python setup.py sdist 11 | 12 | 4. twine check dist/ {}.tar.gz 13 | 14 | 5. upload: twine upload --repository pypi dist/{}.tar.gz 15 | 16 | pip install --upgrade -i https://test.pypi.org/simple/ pyroombaadapter 17 | """ 18 | 19 | from setuptools import setup, find_packages 20 | import os 21 | PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) 22 | 23 | # read __version__ 24 | with open(PROJECT_PATH + "/pycoolplot/VERSION", 'r') as fd: 25 | __version__ = fd.readline().rstrip('\n') 26 | 27 | setup( 28 | name="PyCoolPlot", 29 | version=__version__, 30 | url="https://github.com/AtsushiSakai/PyCoolPlot", 31 | author="Atsushi Sakai", 32 | author_email="asakai.amsl@gmail.com", 33 | maintainer='Atsushi Sakai', 34 | maintainer_email='asakai.amsl@gmail.com', 35 | description=("A cool plotting module in Python"), 36 | long_description=open('README.md').read(), 37 | long_description_content_type='text/markdown', 38 | python_requires='>3.6.0', 39 | license="MIT", 40 | keywords="python plot matplotlib", 41 | packages=find_packages(), 42 | classifiers=[ 43 | 'Programming Language :: Python :: 3', 44 | 'License :: OSI Approved :: MIT License', 45 | 'Topic :: Scientific/Engineering :: Visualization', 46 | ], 47 | install_requires=[ 48 | "numpy", 49 | "matplotlib", 50 | "pandas", 51 | ], 52 | ) 53 | --------------------------------------------------------------------------------