{"id":14977853,"url":"https://github.com/philippeller/dama","last_synced_at":"2025-07-19T18:04:59.580Z","repository":{"id":53998998,"uuid":"124921342","full_name":"philippeller/dama","owner":"philippeller","description":"Look at data in different ways","archived":false,"fork":false,"pushed_at":"2024-10-01T08:46:29.000Z","size":34999,"stargazers_count":9,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-01T12:44:06.059Z","etag":null,"topics":["array","axes","axis","data-science","grid","griddata","histogram","jupyter","map","numpy","translation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/philippeller.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-12T16:50:31.000Z","updated_at":"2024-11-28T08:30:03.000Z","dependencies_parsed_at":"2022-08-13T05:50:47.091Z","dependency_job_id":null,"html_url":"https://github.com/philippeller/dama","commit_stats":null,"previous_names":["philippeller/dragoman"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippeller%2Fdama","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippeller%2Fdama/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippeller%2Fdama/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philippeller%2Fdama/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/philippeller","download_url":"https://codeload.github.com/philippeller/dama/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238608265,"owners_count":19500348,"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","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":["array","axes","axis","data-science","grid","griddata","histogram","jupyter","map","numpy","translation"],"created_at":"2024-09-24T13:56:26.646Z","updated_at":"2025-02-13T06:33:16.769Z","avatar_url":"https://github.com/philippeller.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dama - Data Manipulator\n\nThe dama python library guides you through your data and translates between different representations.\nIts aim is to offer a consistant and pythonic way to handle different datasaets and translations between them.\nA dataset can for instance be simple colum/row data, or it can be data on a grid.\n\nOne of the key features of dama is the seamless translation from one data represenation into any other. \nConvenience `pyplot` plotting functions are also available, in order to produce standard plots without any hassle.\n\n## Installation\n\n* `pip install dama`\n\n## Getting Started\n\n\n```python\nimport numpy as np\nimport dama as dm\n```\n\n### Grid Data\n\n`GridData` is a collection of individual `GridArrays`. Both have a defined `grid`, here we initialize the grid in the constructor through simple keyword arguments resulting in a 2d grid with axes `x` and `y`\n\n\n```python\ng = dm.GridData(x = np.linspace(0,3*np.pi, 30),\n                y = np.linspace(0,2*np.pi, 20),\n               )\n```\n\nFilling one array with some sinusoidal functions, called `a` here\n\n\n```python\ng['a'] = np.sin(g['x']) * np.cos(g['y'])\n```\n\nAs a shorthand, we can also use attributes instead of items:\n\n\n```python\ng.a = np.sin(g.x) * np.cos(g.y)\n```\n\nin 1-d and 2-d they render as html in jupyter notebooks\n\nIt can be plotted easily in case of 1-d and 2-d grids\n\n\n```python\ng.plot(cbar=True);\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_10_0.png)\n    \n\n\nLet's interpolate the values to 200 points along each axis and plot\n\n\n```python\ng.interp(x=200, y=200).plot(cbar=True);\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_12_0.png)\n    \n\n\nExecutions of (most) translation methods is _lazy_. That means that the computation only happens if a specific variable is used. This can have some side effects, that when you maipulate the original data before the translation is evaluated. just something to be aware of.\n\nMasking, and item assignement also is supported\n\n\n```python\ng.a[g.a \u003e 0.3]\n```\n\n\n\n\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ey \\ x\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0.325\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0.65\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e\u003cb\u003e8.77\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e9.1\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e9.42\u003c/b\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e0\u003c/b\u003e    \u003c/td\u003e\u003ctd\u003e--      \u003c/td\u003e\u003ctd\u003e0.319       \u003c/td\u003e\u003ctd\u003e0.605      \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e0.605      \u003c/td\u003e\u003ctd\u003e0.319     \u003c/td\u003e\u003ctd\u003e--         \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e0.331\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e--      \u003c/td\u003e\u003ctd\u003e0.302       \u003c/td\u003e\u003ctd\u003e0.572      \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e0.572      \u003c/td\u003e\u003ctd\u003e0.302     \u003c/td\u003e\u003ctd\u003e--         \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e0.661\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e--      \u003c/td\u003e\u003ctd\u003e--          \u003c/td\u003e\u003ctd\u003e0.478      \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e0.478      \u003c/td\u003e\u003ctd\u003e--        \u003c/td\u003e\u003ctd\u003e--         \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e...         \u003c/td\u003e\u003ctd\u003e...     \u003c/td\u003e\u003ctd\u003e...         \u003c/td\u003e\u003ctd\u003e...        \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e...        \u003c/td\u003e\u003ctd\u003e...       \u003c/td\u003e\u003ctd\u003e...        \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e5.62\u003c/b\u003e \u003c/td\u003e\u003ctd\u003e--      \u003c/td\u003e\u003ctd\u003e--          \u003c/td\u003e\u003ctd\u003e0.478      \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e0.478      \u003c/td\u003e\u003ctd\u003e--        \u003c/td\u003e\u003ctd\u003e--         \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e5.95\u003c/b\u003e \u003c/td\u003e\u003ctd\u003e--      \u003c/td\u003e\u003ctd\u003e0.302       \u003c/td\u003e\u003ctd\u003e0.572      \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e0.572      \u003c/td\u003e\u003ctd\u003e0.302     \u003c/td\u003e\u003ctd\u003e--         \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e6.28\u003c/b\u003e \u003c/td\u003e\u003ctd\u003e--      \u003c/td\u003e\u003ctd\u003e0.319       \u003c/td\u003e\u003ctd\u003e0.605      \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e0.605      \u003c/td\u003e\u003ctd\u003e0.319     \u003c/td\u003e\u003ctd\u003e--         \u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n\nThe objects are also numpy compatible and indexable by index (integers) or value (floats). Numpy functions with `axis` keywords accept either the name(s) of the axis, e.g. here `x` and therefore is independent of axis ordering, or the usual integer indices.\n\n\n```python\ng[10::-1, :np.pi:2]\n```\n\n\n\n\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ey \\ x\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e3.25\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e2.92\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e2.6\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0.65\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0.325\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0\u003c/b\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e0\u003c/b\u003e    \u003c/td\u003e\u003ctd\u003ea = -0.108 \u003c/td\u003e\u003ctd\u003ea = 0.215  \u003c/td\u003e\u003ctd\u003ea = 0.516 \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003ea = 0.605  \u003c/td\u003e\u003ctd\u003ea = 0.319   \u003c/td\u003e\u003ctd\u003ea = 0   \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e0.661\u003c/b\u003e\u003c/td\u003e\u003ctd\u003ea = -0.0853\u003c/td\u003e\u003ctd\u003ea = 0.17   \u003c/td\u003e\u003ctd\u003ea = 0.407 \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003ea = 0.478  \u003c/td\u003e\u003ctd\u003ea = 0.252   \u003c/td\u003e\u003ctd\u003ea = 0   \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e1.32\u003c/b\u003e \u003c/td\u003e\u003ctd\u003ea = -0.0265\u003c/td\u003e\u003ctd\u003ea = 0.0528 \u003c/td\u003e\u003ctd\u003ea = 0.127 \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003ea = 0.149  \u003c/td\u003e\u003ctd\u003ea = 0.0784  \u003c/td\u003e\u003ctd\u003ea = 0   \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e1.98\u003c/b\u003e \u003c/td\u003e\u003ctd\u003ea = 0.0434 \u003c/td\u003e\u003ctd\u003ea = -0.0864\u003c/td\u003e\u003ctd\u003ea = -0.207\u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003ea = -0.243 \u003c/td\u003e\u003ctd\u003ea = -0.128  \u003c/td\u003e\u003ctd\u003ea = -0  \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e2.65\u003c/b\u003e \u003c/td\u003e\u003ctd\u003ea = 0.0951 \u003c/td\u003e\u003ctd\u003ea = -0.189 \u003c/td\u003e\u003ctd\u003ea = -0.453\u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003ea = -0.532 \u003c/td\u003e\u003ctd\u003ea = -0.281  \u003c/td\u003e\u003ctd\u003ea = -0  \u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n\n\n```python\nnp.sum(g[10::-1, :np.pi:2].T, axis='x')\n```\n\n\n\n\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ey\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e0.661\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e1.32\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e1.98\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e2.65\u003c/b\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ea\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e6.03    \u003c/td\u003e\u003ctd\u003e4.76        \u003c/td\u003e\u003ctd\u003e1.48       \u003c/td\u003e\u003ctd\u003e-2.42      \u003c/td\u003e\u003ctd\u003e-5.3       \u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n\n### Comparison\nAs comparison to point out the convenience, an alternative way without using `dama` to achieve the above would look something like the follwoing for creating and plotting the array:\n\u003e ```\n\u003e x = np.linspace(0,3*np.pi, 30)\n\u003e y = np.linspace(0,2*np.pi, 20) \n\u003e\n\u003e xx, yy = np.meshgrid(x, y)\n\u003e a = np.sin(xx) * np.cos(yy)\n\u003e\n\u003e import matplotlib.pyplot as plt\n\u003e \n\u003e x_widths = np.diff(x)\n\u003e x_pixel_boundaries = np.concatenate([[x[0] - 0.5*x_widths[0]], x[:-1] + 0.5*x_widths, [x[-1] + 0.5*x_widths[-1]]])\n\u003e y_widths = np.diff(y)\n\u003e y_pixel_boundaries = np.concatenate([[y[0] - 0.5*y_widths[0]], y[:-1] + 0.5*y_widths, [y[-1] + 0.5*y_widths[-1]]])\n\u003e \n\u003e pc = plt.pcolormesh(x_pixel_boundaries, y_pixel_boundaries, a)\n\u003e plt.gca().set_xlabel('x')\n\u003e plt.gca().set_ylabel('y')\n\u003e cb = plt.colorbar(pc)\n\u003e cb.set_label('a')\n\u003e ```\n\nand for doing the interpolation:\n\n\u003e ```\n\u003e from scipy.interpolate import griddata\n\u003e \n\u003e interp_x = np.linspace(0,3*np.pi, 200)\n\u003e interp_y = np.linspace(0,2*np.pi, 200) \n\u003e \n\u003e grid_x, grid_y = np.meshgrid(interp_x, interp_y)\n\u003e \n\u003e points = np.vstack([xx.flatten(), yy.flatten()]).T\n\u003e values = a.flatten()\n\u003e \n\u003e interp_a = griddata(points, values, (grid_x, grid_y), method='cubic')\n\u003e ```\n\n### PointData\n\nAnother representation of data is `PointData`, which is not any different of a dictionary holding same-length nd-arrays or a pandas `DataFrame` (And can actually be instantiated with those).\n\n\n```python\np = dm.PointData()\np.x = np.random.randn(100_000)\np.a = np.random.rand(p.size) * p.x**2\n```\n\n\n```python\np\n```\n\n\n\n\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ex\u003c/b\u003e\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.0341 \u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.212\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.517\u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e1.27\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.827\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e1.57 \u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ea\u003c/b\u003e\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.00106\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.035\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.18 \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e1.59\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.246\u003c/td\u003e\u003ctd style=\"text-align: right;\"\u003e0.201\u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n\n\n```python\np.plot()\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_23_0.png)\n    \n\n\nMaybe a correlation plot would be more insightful:\n\n\n```python\np.plot('x', 'a', '.');\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_25_0.png)\n    \n\n\nThis can now seamlessly be translated into `Griddata`, for example taking the data binwise in `x` in 20 bins, and in each bin summing up points:\n\n\n```python\np.binwise(x=20).sum()\n```\n\n\n\n\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ex\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[-4.392 -3.962]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[-3.962 -3.532]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[-3.532 -3.102]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[2.916 3.346]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[3.346 3.776]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[3.776 4.206]\u003c/b\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ea\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e29                    \u003c/td\u003e\u003ctd\u003e131                   \u003c/td\u003e\u003ctd\u003e456                   \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e631                 \u003c/td\u003e\u003ctd\u003e163                 \u003c/td\u003e\u003ctd\u003e77.7                \u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n\n\n```python\np.binwise(x=20).sum().plot();\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_28_0.png)\n    \n\n\nThis is equivalent of making a weighted histogram, while the latter is faster.\n\n\n```python\np.histogram(x=20).a\n```\n\n\n\n\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003ex\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[-4.392 -3.962]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[-3.962 -3.532]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[-3.532 -3.102]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[2.916 3.346]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[3.346 3.776]\u003c/b\u003e\u003c/td\u003e\u003ctd\u003e\u003cb\u003e[3.776 4.206]\u003c/b\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003cb\u003e\u003c/b\u003e \u003c/td\u003e\u003ctd\u003e29                    \u003c/td\u003e\u003ctd\u003e131                   \u003c/td\u003e\u003ctd\u003e456                   \u003c/td\u003e\u003ctd\u003e...\u003c/td\u003e\u003ctd\u003e631                 \u003c/td\u003e\u003ctd\u003e163                 \u003c/td\u003e\u003ctd\u003e77.7                \u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n\n\n```python\nnp.allclose(p.histogram(x=10).a, p.binwise(x=10).sum().a)\n```\n\n\n\n\n    True\n\n\n\nThere is also KDE in n-dimensions available, for example:\n\n\n```python\np.kde(x=1000).a.plot();\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_33_0.png)\n    \n\n\n`GridArrays` can also hold multi-dimensional values, like RGB images or here 5 values from the percentile function. Let's plot those as bands:\n\n\n```python\np.binwise(x=20).quantile(q=[0.1, 0.3, 0.5, 0.7, 0.9]).plot_bands()\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_35_0.png)\n    \n\n\nWhen we specify `x` with an array, we e gives a list of points to binwise. So the resulting plot will consist of points, not bins.\n\n\n```python\np.binwise(x=np.linspace(-3,3,10)).quantile(q=[0.1, 0.3, 0.5, 0.7, 0.9]).plot_bands(lines=True, filled=True, linestyles=[':', '--', '-'], lw=1)\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_37_0.png)\n    \n\n\n This is not the same as using edges as in the example below, hence also the plots look different.\n\n\n```python\np.binwise(x=dm.Edges(np.linspace(-3,3,10))).quantile(q=[0.1, 0.3, 0.5, 0.7, 0.9]).plot_bands(lines=True, filled=True, linestyles=[':', '--', '-'], lw=1)\n```\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_39_0.png)\n    \n\n\n### Saving and loading\n\nDama supports the pickle protocol, and objects can be stored like:\n```python\ndm.save(\"filename.pkl\", obj)\n```\n\nAnd read back like:\n```python\nobj = dm.read(\"filename.pkl\")\n```\n\n# Example gallery\n\nThis is just to illustrate some different, seemingly random applications, resulting in various plots. All starting from some random data points\n\n\n```python\nfrom matplotlib import pyplot as plt\n```\n\n\n```python\np = dm.PointData()\np.x = np.random.rand(10_000)\np.y = np.random.randn(p.size) * np.sin(p.x*3*np.pi) * p.x\np.a = p.y/p.x\n```\n\n\n```python\nfig, ax = plt.subplots(4,4,figsize=(20,20))\nax = ax.flatten()\n\n# First row\np.y.plot(ax=ax[0])\np.plot('x', 'y', '.', ax=ax[1])\np.plot_scatter('x', 'y', c='a', s=1, cmap=dm.cm.spectrum, ax=ax[2])\np.interp(x=100, y=100, method=\"nearest\").a.plot(ax=ax[3])\n\n# Second row\nnp.log(1 + p.histogram(x=100, y=100).counts).plot(ax=ax[4])\np.kde(x=100, y=100, bw=(0.02, 0.05)).density.plot(cmap=dm.cm.afterburner_r, ax=ax[5])\np.histogram(x=10, y=10).interp(x=100,y=100).a.plot(cmap=\"RdBu\", ax=ax[6])\np.histogram(x=100, y=100).counts.median_filter(10).plot(ax=ax[7])\n\n# Third row\np.binwise(x=100).quantile(q=[0.1, 0.3, 0.5, 0.7, 0.9]).y.plot_bands(ax=ax[8])\np.binwise(x=100).quantile(q=[0.1, 0.3, 0.5, 0.7, 0.9]).y.gaussian_filter((2.5,0)).interp(x=500).plot_bands(filled=False, lines=True, linestyles=[':', '--', '-'],ax=ax[9])\np.binwise(a=100).mean().y.plot(ax=ax[10])\np.binwise(a=100).std().y.plot(ax=ax[10])\np.histogram(x=100, y=100).counts.std(axis='x').plot(ax=ax[11])\n\n# Fourth row\nnp.log(p.histogram(x=100, y=100).counts + 1).gaussian_filter(0.5).plot_contour(cmap=dm.cm.passion_r, ax=ax[12])\np.histogram(x=30, y=30).gaussian_filter(1).lookup(p).plot_scatter('x', 'y', 'a', 1, cmap='Spectral', ax=ax[13])\nh = p.histogram(y=100, x=np.logspace(-1,0,100)).a.T\nh[h\u003e0].plot(ax=ax[14])\nh[1/3:2/3].plot(ax=ax[15])\n```\n\n\n\n\n    \u003cmatplotlib.collections.QuadMesh at 0x7f8a0315d1f0\u003e\n\n\n\n\n    \n![png](https://raw.githubusercontent.com/philippeller/dama/master/README_files/README_44_1.png)\n    \n\n\n\n```python\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilippeller%2Fdama","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphilippeller%2Fdama","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilippeller%2Fdama/lists"}