{"id":13813577,"url":"https://github.com/tammoippen/plotille","last_synced_at":"2025-10-21T05:22:07.725Z","repository":{"id":26552842,"uuid":"105019800","full_name":"tammoippen/plotille","owner":"tammoippen","description":"Plot in the terminal using braille dots.","archived":false,"fork":false,"pushed_at":"2025-01-22T18:19:02.000Z","size":4849,"stargazers_count":476,"open_issues_count":7,"forks_count":20,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-03T13:59:02.740Z","etag":null,"topics":["braille","heatmap","histogram","images","plot","plotting","python","scatter-plot","terminal","timeseries","unicode","visualization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tammoippen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-09-27T13:10:42.000Z","updated_at":"2025-08-29T06:49:07.000Z","dependencies_parsed_at":"2024-06-18T17:07:32.845Z","dependency_job_id":"cdaacb2a-b08d-42ef-b8fd-90a03a482151","html_url":"https://github.com/tammoippen/plotille","commit_stats":{"total_commits":125,"total_committers":3,"mean_commits":"41.666666666666664","dds":"0.016000000000000014","last_synced_commit":"4a47f5501c7e37bf4f217ba39c519f52119f56c5"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/tammoippen/plotille","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tammoippen%2Fplotille","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tammoippen%2Fplotille/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tammoippen%2Fplotille/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tammoippen%2Fplotille/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tammoippen","download_url":"https://codeload.github.com/tammoippen/plotille/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tammoippen%2Fplotille/sbom","scorecard":{"id":867328,"data":{"date":"2025-08-11","repo":{"name":"github.com/tammoippen/plotille","commit":"ebe04dfe1479adfdb084a90906bf54a7a63bc2c0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:17","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:18","Warn: no topLevel permission defined: .github/workflows/CI.yml:1","Warn: no topLevel permission defined: .github/workflows/Publish.yml:1","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":1,"reason":"Found 3/30 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/CI.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/CI.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/CI.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/CI.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/CI.yml:64: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/CI.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/CI.yml:79: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/CI.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Publish.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/Publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Publish.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/Publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/Publish.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/Publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/Publish.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/Publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/tammoippen/plotille/codeql.yml/master?enable=pin","Info:   0 out of  10 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":2,"reason":"8 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-3f63-hfp8-52jq","Warn: Project is vulnerable to: GHSA-44wm-f244-xhp3","Warn: Project is vulnerable to: PYSEC-2023-227 / GHSA-8ghj-p4vj-mr35","Warn: Project is vulnerable to: GHSA-j7hp-h8jx-5ppr","Warn: Project is vulnerable to: PYSEC-2023-175","Warn: Project is vulnerable to: PYSEC-2022-42969","Warn: Project is vulnerable to: PYSEC-2025-49 / GHSA-5rjg-fvgr-3xxf","Warn: Project is vulnerable to: GHSA-cx63-2mw6-8hw5"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T03:00:48.990Z","repository_id":26552842,"created_at":"2025-08-24T03:00:48.990Z","updated_at":"2025-08-24T03:00:48.990Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280207283,"owners_count":26290628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["braille","heatmap","histogram","images","plot","plotting","python","scatter-plot","terminal","timeseries","unicode","visualization"],"created_at":"2024-08-04T04:01:21.944Z","updated_at":"2025-10-21T05:22:07.685Z","avatar_url":"https://github.com/tammoippen.png","language":"Python","readme":"![Hero Plotille](https://github.com/tammoippen/plotille/raw/master/imgs/hero.png)\n\n# Plotille\n\n[![CI](https://github.com/tammoippen/plotille/actions/workflows/CI.yml/badge.svg)](https://github.com/tammoippen/plotille/actions/workflows/CI.yml)\n[![codecov](https://codecov.io/gh/tammoippen/plotille/branch/master/graph/badge.svg?token=OGWI832JNM)](https://codecov.io/gh/tammoippen/plotille)\n[![Tested CPython Versions](https://img.shields.io/badge/cpython-3.8%2C%203.9%2C%203.10%2C%203.11%2C%203.12-brightgreen.svg)](https://img.shields.io/badge/cpython-3.8%2C%203.9%2C%203.10%2C%203.11%2C%203.12-brightgreen.svg)\n[![Tested PyPy Versions](https://img.shields.io/badge/pypy-3.8%2C%203.9-brightgreen.svg)](https://img.shields.io/badge/pypy-3.8%2C%203.9%2C%203.10-brightgreen.svg)\n[![PyPi version](https://img.shields.io/pypi/v/plotille.svg)](https://pypi.python.org/pypi/plotille)\n[![Downloads](https://pepy.tech/badge/plotille/month)](https://pepy.tech/project/plotille)\n[![PyPi license](https://img.shields.io/pypi/l/plotille.svg)](https://pypi.python.org/pypi/plotille)\n\nPlots, scatter plots, histograms and heatmaps in the terminal using braille dots, and foreground and background colors - with no dependencies. Make complex figures using the Figure class or make fast and simple plots using graphing function - similar to a very small sibling to matplotlib. Or use the canvas to plot dots, lines and images yourself.\n\nInstall:\n\n```sh\npip install plotille\n```\n\nSimilar to other libraries:\n\n- like [drawille](https://github.com/asciimoo/drawille), but focused on graphing – plus X/Y-axis.\n- like [termplot](https://github.com/justnoise/termplot), but with braille (finer dots), left to right histogram and linear interpolation for plotting function.\n- like [termgraph](https://github.com/sgeisler/termgraph) (not on pypi), but very different style.\n- like [terminalplot](https://github.com/kressi/terminalplot), but with braille, X/Y-axis, histogram, linear interpolation.\n\nBasic support for timeseries plotting is provided with release 3.2: for any `X` or `Y` values you can also add `datetime.datetime`, `pendulum.datetime` or `numpy.datetime64` values. Labels are generated respecting the difference of `x_limits` and `y_limits`.\n\nSupport for heatmaps using background colors for figures and displaying images binary with braille, or in color with background colors using the canvas - provided with release 4.0\n\nIf you are still using python 2.7, please use plotille v4 or before. With v5 I am dropping support for python 2.7, as the effort to maintain the discontinued version is too much.\n\n## Documentation\n\n```python\nIn [1]: import plotille\nIn [2]: import numpy as np\nIn [3]: X = np.sort(np.random.normal(size=1000))\n```\n\n### Figure\n\nTo construct plots the recommended way is to use a `Figure`:\n\n```python\nIn [12]: plotille.Figure?\nInit signature: plotille.Figure()\nDocstring:\nFigure class to compose multiple plots.\n\nWithin a Figure you can easily compose many plots, assign labels to plots\nand define the properties of the underlying Canvas. Possible properties that\ncan be defined are:\n\n    width, height: int    Define the number of characters in X / Y direction\n                          which are used for plotting.\n    x_limits: float       Define the X limits of the reference coordinate system,\n                          that will be plottered.\n    y_limits: float       Define the Y limits of the reference coordinate system,\n                          that will be plottered.\n    color_mode: str       Define the used color mode. See `plotille.color()`.\n    with_colors: bool     Define, whether to use colors at all.\n    background: multiple  Define the background color.\n    x_label, y_label: str Define the X / Y axis label.\n```\n\nBasically, you create a `Figure`, define the properties and add your plots. Using the `show()` function, the `Figure` generates the plot using a new canvas:\n\n```python\nIn [13] fig = plotille.Figure()\nIn [14] fig.width = 60\nIn [15] fig.height = 30\nIn [16] fig.set_x_limits(min_=-3, max_=3)\nIn [17] fig.set_y_limits(min_=-1, max_=1)\nIn [18] fig.color_mode = 'byte'\nIn [19] fig.plot([-0.5, 1], [-1, 1], lc=25, label='First line')\nIn [20] fig.scatter(X, np.sin(X), lc=100, label='sin')\nIn [21] fig.plot(X, (X+2)**2 , lc=200, label='square')\nIn [22] print(fig.show(legend=True))\n```\n\n![Example figure](https://github.com/tammoippen/plotille/raw/master/imgs/figure.png)\n\nThe available plotting functions are:\n\n```python\n# create a plot with linear interpolation between points\nFigure.plot(self, X, Y, lc=None, interp='linear', label=None, marker=None)\n# create a scatter plot with no interpolation between points\nFigure.scatter(self, X, Y, lc=None, label=None, marker=None)\n# create a histogram over X\nFigure.histogram(self, X, bins=160, lc=None)\n# print texts at coordinates X, Y\nFigure.text(self, X, Y, texts, lc=None)\n\n# The following functions use relative coordinates on the canvas\n# i.e. all coordinates are \\in [0, 1]\n# plot a vertical line at x\nFigure.axvline(self, x, ymin=0, ymax=1, lc=None)\n# plot a vertical rectangle from (xmin,ymin) to (xmax, ymax).\nFigure.axvspan(self, xmin, xmax, ymin=0, ymax=1, lc=None)\n# plot a horizontal line at y\nFigure.axhline(self, y, xmin=0, xmax=1, lc=None)\n# plot a horizontal rectangle from (xmin,ymin) to (xmax, ymax).\nFigure.axhspan(self, ymin, ymax, xmin=0, xmax=1, lc=None)\n\n# Display data as an image, i.e. on a 2D regular raster.\nFigure.imgshow(self, X, cmap=None)\n```\n\nOther interesting functions are:\n\n```python\n# remove all plots, texts, spans and images from the figure\nFigure.clear(self)\n# Create a canvas, plot the registered plots and return the string for displaying the plot\nFigure.show(self, legend=False)\n```\n\nPlease have a look at the [`examples/`](./examples) folder.\n\n### Graphing\n\nThere are some utility functions for fast graphing of single plots.\n\n#### Plot\n\n```python\nIn [4]: plotille.plot?\nSignature:\nplotille.plot(\n    X,\n    Y,\n    width=80,\n    height=40,\n    X_label='X',\n    Y_label='Y',\n    linesep=os.linesep,\n    interp='linear',\n    x_min=None,\n    x_max=None,\n    y_min=None,\n    y_max=None,\n    lc=None,\n    bg=None,\n    color_mode='names',\n    origin=True,\n    marker=None,\n)\nDocstring:\nCreate plot with X , Y values and linear interpolation between points\n\nParameters:\n    X: List[float]         X values.\n    Y: List[float]         Y values. X and Y must have the same number of entries.\n    width: int             The number of characters for the width (columns) of the canvas.\n    height: int             The number of characters for the height (rows) of the canvas.\n    X_label: str           Label for X-axis.\n    Y_label: str           Label for Y-axis. max 8 characters.\n    linesep: str           The requested line separator. default: os.linesep\n    interp: Optional[str]  Specify interpolation; values None, 'linear'\n    x_min, x_max: float    Limits for the displayed X values.\n    y_min, y_max: float    Limits for the displayed Y values.\n    lc: multiple           Give the line color.\n    bg: multiple           Give the background color.\n    color_mode: str        Specify color input mode; 'names' (default), 'byte' or 'rgb'\n                           see plotille.color.__docs__\n    origin: bool           Whether to print the origin. default: True\n    marker: str            Instead of braille dots set a marker char for actual values.\n\nReturns:\n    str: plot over `X`, `Y`.\n\nIn [5]: print(plotille.plot(X, np.sin(X), height=30, width=60))\n```\n\n![Example plot](https://github.com/tammoippen/plotille/raw/master/imgs/plot.png)\n\n#### Scatter\n\n```python\nIn [6]: plotille.scatter?\nSignature:\nplotille.scatter(\n    X,\n    Y,\n    width=80,\n    height=40,\n    X_label='X',\n    Y_label='Y',\n    linesep='\\n',\n    x_min=None,\n    x_max=None,\n    y_min=None,\n    y_max=None,\n    lc=None,\n    bg=None,\n    color_mode='names',\n    origin=True,\n    marker=None,\n)\nDocstring:\nCreate scatter plot with X , Y values\n\nBasically plotting without interpolation:\n    `plot(X, Y, ... , interp=None)`\n\nParameters:\n    X: List[float]       X values.\n    Y: List[float]       Y values. X and Y must have the same number of entries.\n    width: int           The number of characters for the width (columns) of the canvas.\n    height: int           The number of characters for the height (rows) of the canvas.\n    X_label: str         Label for X-axis.\n    Y_label: str         Label for Y-axis. max 8 characters.\n    linesep: str         The requested line separator. default: os.linesep\n    x_min, x_max: float  Limits for the displayed X values.\n    y_min, y_max: float  Limits for the displayed Y values.\n    lc: multiple         Give the line color.\n    bg: multiple         Give the background color.\n    color_mode: str      Specify color input mode; 'names' (default), 'byte' or 'rgb'\n                         see plotille.color.__docs__\n    origin: bool         Whether to print the origin. default: True\n    marker: str          Instead of braille dots set a marker char.\n\nReturns:\n    str: scatter plot over `X`, `Y`.\n\nIn [7]: print(plotille.scatter(X, np.sin(X), height=30, width=60))\n```\n\n![Example scatter](https://github.com/tammoippen/plotille/raw/master/imgs/scatter.png)\n\n#### Hist\n\nInspired by [crappyhist](http://kevinastraight.x10host.com/2013/12/28/python-histograms-from-the-console/) (link is gone, but I made a [gist](https://gist.github.com/tammoippen/4474e838e969bf177155231ebba52386)).\n\n```python\nIn [8]: plotille.hist?\nSignature:\nplotille.hist(\n    X,\n    bins=40,\n    width=80,\n    log_scale=False,\n    linesep='\\n',\n    lc=None,\n    bg=None,\n    color_mode='names',\n)\nDocstring:\nCreate histogram over `X` from left to right\n\nThe values on the left are the center of the bucket, i.e. `(bin[i] + bin[i+1]) / 2`.\nThe values on the right are the total counts of this bucket.\n\nParameters:\n    X: List[float]       The items to count over.\n    bins: int            The number of bins to put X entries in (rows).\n    width: int           The number of characters for the width (columns).\n    log_scale: bool      Scale the histogram with `log` function.\n    linesep: str         The requested line separator. default: os.linesep\n    lc: multiple         Give the line color.\n    bg: multiple         Give the background color.\n    color_mode: str      Specify color input mode; 'names' (default), 'byte' or 'rgb'\n                         see plotille.color.__docs__\n\nReturns:\n    str: histogram over `X` from left to right.\n\nIn [9]: print(plotille.hist(np.random.normal(size=10000)))\n```\n\n![Example hist](https://github.com/tammoippen/plotille/raw/master/imgs/hist.png)\n\n#### Hist (aggregated)\n\nThis function allows you to create a histogram when your data is already aggregated (aka you don't have access to raw values, but you have access to bins and counts for each bin).\n\nThis comes handy when working with APIs such as [OpenTelemetry Metrics API](https://opentelemetry-python.readthedocs.io/en/latest/api/metrics.html)\nwhere views such as [ExplicitBucketHistogramAggregation](https://opentelemetry-python.readthedocs.io/en/latest/sdk/metrics.view.html#opentelemetry.sdk.metrics.view.ExplicitBucketHistogramAggregation)\nonly expose access to aggregated values (counts for each bin / bucket).\n\n```python\nIn [8]: plotille.hist_aggregated?\nSignature:\nplotille.hist_aggregated(\n    counts,\n    bins,\n    width=80,\n    log_scale=False,\n    linesep='\\n',\n    lc=None,\n    bg=None,\n    color_mode='names',\n)\nDocstring:\nCreate histogram for aggregated data.\n\nParameters:\n    counts: List[int]    Counts for each bucket.\n    bins: List[float]    Limits for the bins for the provided counts: limits for\n                         bin `i` are `[bins[i], bins[i+1])`.\n                         Hence, `len(bins) == len(counts) + 1`.\n    width: int           The number of characters for the width (columns).\n    log_scale: bool      Scale the histogram with `log` function.\n    linesep: str         The requested line separator. default: os.linesep\n    lc: multiple         Give the line color.\n    bg: multiple         Give the background color.\n    color_mode: str      Specify color input mode; 'names' (default), 'byte' or 'rgb'\n                         see plotille.color.__docs__\nReturns:\n    str: histogram over `X` from left to right.\n\nIn [9]: counts = [1945, 0, 0, 0, 0, 0, 10555, 798, 0, 28351, 0]\nIn [10]: bins = [float('-inf'), 10, 50, 100, 200, 300, 500, 800, 1000, 2000, 10000, float('+inf')]\nIn [11]: print(plotille.hist_aggregated(counts, bins))\n```\n\nKeep in mind that there must always be n+1 bins (n is a total number of count values, 11 in the example above).\n\nIn this example the first bin is from [-inf, 10) with a count of 1945 and the last bin is from [10000, +inf] with a count of 0.\n\n![Example hist](https://github.com/tammoippen/plotille/raw/master/imgs/hist_aggregated.png)\n\n#### Histogram\n\nThere is also another more 'usual' histogram function available:\n\n```python\nIn [10]: plotille.histogram?\nSignature:\nplotille.histogram(\n    X,\n    bins=160,\n    width=80,\n    height=40,\n    X_label='X',\n    Y_label='Counts',\n    linesep='\\n',\n    x_min=None,\n    x_max=None,\n    y_min=None,\n    y_max=None,\n    lc=None,\n    bg=None,\n    color_mode='names',\n)\nDocstring:\nCreate histogram over `X`\n\nIn contrast to `hist`, this is the more `usual` histogram from bottom\nto up. The X-axis represents the values in `X` and the Y-axis is the\ncorresponding frequency.\n\nParameters:\n    X: List[float]       The items to count over.\n    bins: int            The number of bins to put X entries in (columns).\n    height: int          The number of characters for the height (rows).\n    X_label: str         Label for X-axis.\n    Y_label: str         Label for Y-axis. max 8 characters.\n    linesep: str         The requested line separator. default: os.linesep\n    x_min, x_max: float  Limits for the displayed X values.\n    y_min, y_max: float  Limits for the displayed Y values.\n    lc: multiple         Give the line color.\n    bg: multiple         Give the background color.\n    color_mode: str      Specify color input mode; 'names' (default), 'byte' or 'rgb'\n                         see plotille.color.__docs__\n\nReturns:\n    str: histogram over `X`.\n\nIn [11]: print(plotille.histogram(np.random.normal(size=10000)))\n```\n\n![Example histogram](https://github.com/tammoippen/plotille/raw/master/imgs/histogram.png)\n\n### Canvas\n\nThe underlying plotting area is modeled as the `Canvas` class:\n\n```python\nIn [12]:  plotille.Canvas?\nInit signature:\nplotille.Canvas(\n    width,\n    height,\n    xmin=0,\n    ymin=0,\n    xmax=1,\n    ymax=1,\n    background=None,\n    **color_kwargs,\n)\nDocstring:\nA canvas object for plotting braille dots\n\nA Canvas object has a `width` x `height` characters large canvas, in which it\ncan plot indivitual braille point, lines out of braille points, rectangles,...\nSince a full braille character has 2 x 4 dots (⣿), the canvas has `width` * 2, `height` * 4\ndots to plot into in total.\n\nIt maintains two coordinate systems: a reference system with the limits (xmin, ymin)\nin the lower left corner to (xmax, ymax) in the upper right corner is transformed\ninto the canvas discrete, i.e. dots, coordinate system (0, 0) to (`width` * 2, `height` * 4).\nIt does so transparently to clients of the Canvas, i.e. all plotting functions\nonly accept coordinates in the reference system. If the coordinates are outside\nthe reference system, they are not plotted.\nInit docstring:\nInitiate a Canvas object\n\nParameters:\n    width: int            The number of characters for the width (columns) of the canvas.\n    height: int            The number of characters for the height (rows) of the canvas.\n    xmin, ymin: float     Lower left corner of reference system.\n    xmax, ymax: float     Upper right corner of reference system.\n    background: multiple  Background color of the canvas.\n    **color_kwargs:       More arguments to the color-function. See `plotille.color()`.\n\nReturns:\n    Canvas object\n```\n\nThe most interesting functions are:\n\n_point:_\n\n```python\nIn [11]: plotille.Canvas.point?\nSignature: plotille.Canvas.point(self, x, y, set_=True, color=None, marker=None)\nDocstring:\nPut a point into the canvas at (x, y) [reference coordinate system]\n\nParameters:\n    x: float         x-coordinate on reference system.\n    y: float         y-coordinate on reference system.\n    set_: bool       Whether to plot or remove the point.\n    color: multiple  Color of the point.\n    marker: str      Instead of braille dots set a marker char.\n```\n\n_line:_\n\n```python\nIn [14]: plotille.Canvas.line?\nSignature: plotille.Canvas.line(self, x0, y0, x1, y1, set_=True, color=None)\nDocstring:\nPlot line between point (x0, y0) and (x1, y1) [reference coordinate system].\n\nParameters:\n    x0, y0: float    Point 0\n    x1, y1: float    Point 1\n    set_: bool       Whether to plot or remove the line.\n    color: multiple  Color of the line.\n```\n\n_rect:_\n\n```python\nIn [15]: plotille.Canvas.rect?\nSignature: plotille.Canvas.rect(self, xmin, ymin, xmax, ymax, set_=True, color=None)\nDocstring:\nPlot rectangle with bbox (xmin, ymin) and (xmax, ymax) [reference coordinate system].\n\nParameters:\n    xmin, ymin: float  Lower left corner of rectangle.\n    xmax, ymax: float  Upper right corner of rectangle.\n    set_: bool         Whether to plot or remove the rect.\n    color: multiple    Color of the rect.\n```\n\n_text:_\n\n```python\nIn [16]: plotille.Canvas.text?\nSignature: plotille.Canvas.text(self, x, y, text, set_=True, color=None)\nDocstring:\nPut some text into the canvas at (x, y) [reference coordinate system]\n\nParameters:\n    x: float         x-coordinate on reference system.\n    y: float         y-coordinate on reference system.\n    set_: bool       Whether to set the text or clear the characters.\n    text: str        The text to add.\n    color: multiple  Color of the point.\n```\n\n_braille_image:_\n\n```python\nIn [17]: plotille.Canvas.braille_image?\nSignature:\nplotille.Canvas.braille_image(\n    self,\n    pixels,\n    threshold=127,\n    inverse=False,\n    set_=True,\n)\nDocstring:\nPrint an image using braille dots into the canvas.\n\nThe pixels and braille dots in the canvas are a 1-to-1 mapping, hence\na 80 x 80 pixel image will need a 40 x 20 canvas.\n\nExample:\n    from PIL import Image\n    import plotille as plt\n\n    img = Image.open(\"/path/to/image\")\n    img = img.convert('L')\n    img = img.resize((80, 80))\n    cvs = plt.Canvas(40, 20)\n    cvs.braille_image(img.getdata(), 125)\n    print(cvs.plot())\n\nParameters:\n    pixels: list[number]  All pixels of the image in one list.\n    threshold: float      All pixels above this threshold will be\n                          drawn.\n    inverse: bool         Whether to invert the image.\n    set_: bool            Whether to plot or remove the dots.\n```\n\n_image:_\n\n```python\nIn [18]: plotille.Canvas.image?\nSignature: plotille.Canvas.image(self, pixels, set_=True)\nDocstring:\nPrint an image using background colors into the canvas.\n\nThe pixels of the image and the characters in the canvas are a\n1-to-1 mapping, hence a 80 x 80 image will need a 80 x 80 canvas.\n\nExample:\n    from PIL import Image\n    import plotille as plt\n\n    img = Image.open(\"/path/to/image\")\n    img = img.convert('RGB')\n    img = img.resize((40, 40))\n    cvs = plt.Canvas(40, 40, mode='rgb')\n    cvs.image(img.getdata())\n    print(cvs.plot())\n\nParameters:\n    pixels: list[(R,G,B)]  All pixels of the image in one list.\n    set_: bool             Whether to plot or remove the background\n                           colors.\n```\n\n_plot:_\n\n```python\nIn [16]: plotille.Canvas.plot?\nSignature: plotille.Canvas.plot(self, linesep='\\n')\nDocstring:\nTransform canvas into `print`-able string\n\nParameters:\n    linesep: str  The requested line separator. default: os.linesep\n\nReturns:\n    unicode: The canvas as a string.\n```\n\nYou can use it for example to plot a house in the terminal:\n\n```python\nIn [17]: c = Canvas(width=40, height=20)\nIn [18]: c.rect(0.1, 0.1, 0.6, 0.6)\nIn [19]: c.line(0.1, 0.1, 0.6, 0.6)\nIn [20]: c.line(0.1, 0.6, 0.6, 0.1)\nIn [21]: c.line(0.1, 0.6, 0.35, 0.8)\nIn [22]: c.line(0.35, 0.8, 0.6, 0.6)\nIn [23]: print(c.plot())\n```\n\n![House](https://github.com/tammoippen/plotille/raw/master/imgs/house.png)\n\nOr you could render images with braille dots:\n\n```python\nIn [24]: img = Image.open('https://github.com/tammoippen/plotille/raw/master/imgs/ich.jpg')\nIn [25]: img = img.convert('L')\nIn [26]: img = img.resize((80, 80))\nIn [27]: cvs = Canvas(40, 20)\nIn [28]: cvs.braille_image(img.getdata())\nIn [29]: print(cvs.plot())\n```\n\n![Me with dots](https://github.com/tammoippen/plotille/raw/master/imgs/ich-dots.png)\n\nOr you could render images with the background color of characters:\n\n```python\nIn [24]: img = Image.open('https://github.com/tammoippen/plotille/raw/master/imgs/ich.jpg')\nIn [25]: img = img.convert('RGB')\nIn [25]: img = img.resize((80, 40))\nIn [27]: cvs = Canvas(80, 40, mode=\"rgb\")\nIn [28]: cvs.image(img.getdata())\nIn [29]: print(cvs.plot())\n```\n\n![Me with chars](https://github.com/tammoippen/plotille/raw/master/imgs/ich-chars.png)\n\n## Stargazers over time\n\n[![Stargazers over time](https://starchart.cc/tammoippen/plotille.svg)](https://starchart.cc/tammoippen/plotille)\n\n## Sponsoring the project\n\nIf you like the project and want to buy me a coffee, feel free to send some coins ;)\n\n[\u003cimg src=\"https://api.gitsponsors.com/api/badge/img?id=105019800\" height=\"20\"\u003e](https://api.gitsponsors.com/api/badge/link?p=gkBol1u2+g2pjgZGRaDLy4k0XbPDRXdPWJWnueCUGo/wcSsqyE8nr+n9nvqfeuqXee6JhLARGZS5bP0ZvorS7y6t4INyHLtTrprYh9c+MYkqAZeSqNIf7WL0ZRTI070RVQA3L9QW9IZNFlMbulW+BQ==)","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftammoippen%2Fplotille","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftammoippen%2Fplotille","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftammoippen%2Fplotille/lists"}