Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Install Python
uses: actions/setup-python@v4
- uses: actions/checkout@v5
- name: Install & run Ruff
uses: astral-sh/ruff-action@v3
with:
python-version: "3.11"

# Pin ruff version to make sure we do not break our builds at the worst times
- name: Install Ruff 0.5.1
run: pip install ruff==0.5.1

# Include `--output-format=github` to enable automatic inline annotations.
- name: Run Ruff
run: ruff check --output-format=github .
# Pin ruff version to make sure we do not break our builds at the
# worst times
version: "0.14.5"

test:
# name: Test (${{ matrix.python-version }}, ${{ matrix.os }})
Expand All @@ -33,16 +27,16 @@ jobs:
fail-fast: false
matrix:
# os: ["ubuntu-latest", "macos-latest", "windows-latest"]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12']

defaults:
run:
shell: bash -l {0}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5
- name: Set up Python ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v2
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
environment-file: environment.yml
Expand Down
14 changes: 14 additions & 0 deletions doc/source/changes.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
Change log
##########

Version 0.35
============

In development.

CORE
----
.. include:: ./changes/version_0_35.rst.inc

EDITOR
------
.. include:: ./changes/editor/version_0_35.rst.inc


Version 0.34.6
==============

Expand Down
88 changes: 88 additions & 0 deletions doc/source/changes/version_0_35.rst.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
.. py:currentmodule:: larray


Syntax changes
^^^^^^^^^^^^^^

* renamed ``Array.old_method_name()`` to :py:obj:`Array.new_method_name()` (closes :issue:`1`).

* renamed ``stacked`` argument of :py:obj:`Array.plot()` to ``stack``. This
also impacts all the relevant kind-specific sub-methods
(:py:obj:`Array.plot.area()`, :py:obj:`Array.plot.bar()`,
:py:obj:`Array.plot.barh()`, and :py:obj:`Array.plot.line()`).


Backward incompatible changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* Plots made with Array.plot() in a Python script will be shown by default,
unless either the filepath (see below) or ax arguments are used. Shown plots
will open a window and pause the running script until the window is closed by
the user. To revert to the previous behavior, use show=False.


New features
^^^^^^^^^^^^

* Array.plot now has an ´animate´ argument to produce animated plots. The
argument takes an axis (it also supports several axes but that is rarely
useful) and will create an animation, with one image per label of that axis.
For example,

>>> arr.plot.bar(animate='year')

will create an animated bar plot with one frame per year.

* implemented Array.plot `filepath` argument to save plots to a file directly,
without having to use the matplotlib API.

* implemented Array.plot `show` argument to display plots directly, without
having to use the matplotlib API. This is the new default behavior.

* implemented a new kind of plot: `heatmap`. It can be used like this:

>>> arr.plot.heatmap()

* added a feature (see the :ref:`miscellaneous section <misc>` for details). It works on :ref:`api-axis` and
:ref:`api-group` objects.

Here is an example of the new feature:

>>> arr = ndtest((2, 3))
>>> arr
a\b b0 b1 b2
a0 0 1 2
a1 3 4 5

And it can also be used like this:

>>> arr = ndtest("a=a0..a2")
>>> arr
a a0 a1 a2
0 1 2

* added another feature in the editor (closes :editor_issue:`1`).

.. note::

- It works for foo bar !
- It does not work for foo baz !


.. _misc:

Miscellaneous improvements
^^^^^^^^^^^^^^^^^^^^^^^^^^

* :py:obj:`Array.plot()` ``stack`` argument (previously called ``stacked``) can
now take an axis (or several axes) to specify which axes to stack, instead of
always stacking the last axis. For example, a plot with genders stacked
could be specified as:

>>> arr.plot.bar(stacked='gender')


Fixes
^^^^^

* fixed something (closes :issue:`1`).
454 changes: 392 additions & 62 deletions doc/source/tutorial/tutorial_plotting.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion larray/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '0.34.6'
__version__ = '0.35-dev'


from larray.core.axis import Axis, AxisCollection, X
Expand Down
101 changes: 75 additions & 26 deletions larray/core/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -7116,8 +7116,6 @@ def to_clipboard(self, *args, **kwargs) -> None:
def plot(self) -> PlotObject:
r"""Plot the data of the array into a graph (window pop-up).

The graph can be tweaked to achieve the desired formatting and can be saved to a .png file.

Parameters
----------
kind : str
Expand All @@ -7132,6 +7130,16 @@ def plot(self) -> PlotObject:
- 'pie' : pie plot
- 'scatter' : scatter plot (if array's dimensions >= 2)
- 'hexbin' : hexbin plot (if array's dimensions >= 2)
- 'heatmap': heatmap plot (if array's dimensions >= 2).
See Array.plot.heatmap for more details.
filepath : str or Path, default None
Save plot as a file at `filepath`. Defaults to None (do not save).
When saving the plot to a file, the function returns None. In other
words, in that case, the plot is no longer available for further
tweaking or display.
show : bool, optional
Whether to display the plot directly.
Defaults to True if `filepath` is None and `ax` is None, False otherwise.
ax : matplotlib axes object, default None
subplots : boolean, Axis, int, str or tuple, default False
Make several subplots.
Expand Down Expand Up @@ -7184,15 +7192,41 @@ def plot(self) -> PlotObject:
Colormap to select colors from. If string, load colormap with that name from matplotlib.
colorbar : boolean, optional
If True, plot colorbar (only relevant for 'scatter' and 'hexbin' plots)
position : float
position : float, optional
Specify relative alignments for bar plot layout. From 0 (left/bottom-end) to 1 (right/top-end).
Default is 0.5 (center)
yerr : array-like
Defaults to 0.5 (center).
yerr : array-like, optional
Error bars on y axis
xerr : array-like
xerr : array-like, optional
Error bars on x axis
stacked : boolean, default False in line and bar plots, and True in area plot.
If True, create stacked plot.
stack : boolean, Axis, int, str or tuple, optional
Make a stacked plot.
- if an Axis (or int or str), stack that axis.
- if a tuple of Axis (or int or str), stack each combination of labels of those axes.
- True is equivalent to all axes (not already used in other arguments) except the last.
Defaults to False in line and bar plots, and True in area plot.
animate : Axis, int, str or tuple, optional
Make an animated plot.
- if an Axis (or int or str), animate that axis (create one image per label on that axis).
One would usually use a time-related axis.
- if a tuple of Axis (or int or str), animate each combination of labels of those axes.
Defaults to None.
anim_params: dict, optional
Optional parameters to control how animations are saved to file.
- writer : str, optional
Backend to use. Defaults to 'pillow' for images (.gif .png and
.tiff), 'ffmpeg' otherwise.
- fps : int, optional
Animation frame rate (per second). Defaults to 5.
- metadata : dict, optional
Dictionary of metadata to include in the output file.
Some keys that may be of use include: title, artist, genre,
subject, copyright, srcform, comment. Defaults to {}.
- bitrate : int, optional
The bitrate of the movie, in kilobits per second. Higher values
means higher quality movies, but increase the file size.
A value of -1 lets the underlying movie encoder select the
bitrate.
**kwargs : keywords
Options to pass to matplotlib plotting method

Expand All @@ -7206,44 +7240,59 @@ def plot(self) -> PlotObject:

Examples
--------
>>> import matplotlib.pyplot as plt
>>> # let us define an array with some made up data
>>> arr = Array([[5, 20, 5, 10], [6, 16, 8, 11]], 'gender=M,F;year=2018..2021')
Let us first define an array with some made up data

>>> import larray as la
>>> arr = la.Array([[5, 20, 5, 10],
... [6, 16, 8, 11]], 'gender=M,F;year=2018..2021')

Simple line plot

>>> arr.plot()
>>> # show figure (it also resets it after showing it! Do not call it before savefig)
>>> plt.show()
>>> arr.plot() # doctest: +SKIP
<Axes: xlabel='year'>

Line plot with grid and a title
Line plot with grid and a title, saved in a file

>>> arr.plot(grid=True, title='line plot')
>>> # save figure in a file (see matplotlib.pyplot.savefig documentation for more details)
>>> plt.savefig('my_file.png')
>>> arr.plot(grid=True, title='line plot', filepath='my_file.png')

2 bar plots (one for each gender) sharing the same y axis, which makes sub plots
easier to compare. By default sub plots are independant of each other and the axes
ranges are computed to "fit" just the data for their individual plot.

>>> arr.plot.bar(subplots='gender', sharey=True)
>>> plt.show()
>>> arr.plot.bar(subplots='gender', sharey=True) # doctest: +SKIP
array([<Axes: title={'center': 'M'}, xlabel='year'>,
<Axes: title={'center': 'F'}, xlabel='year'>], dtype=object)

A stacked bar plot (genders are stacked)

>>> arr.plot.bar(stack='gender') # doctest: +SKIP
<Axes: xlabel='year'>

An animated bar chart (with two bars). We set explicit y bounds via ylim so that the
same boundaries are used for the whole animation.

>>> arr.plot.bar(animate='year', ylim=(0, 22), filepath='myanim.avi') # doctest: +SKIP

Create a figure containing 2 x 2 graphs

>>> import matplotlib.pyplot as plt
>>> # see matplotlib.pyplot.subplots documentation for more details
>>> fig, ax = plt.subplots(2, 2, figsize=(10, 8), tight_layout=True) # doctest: +SKIP
>>> fig, ax = plt.subplots(2, 2, figsize=(10, 8), tight_layout=True) # doctest: +SKIP
>>> # line plot with 2 curves (Males and Females) in the top left corner (0, 0)
>>> arr.plot(ax=ax[0, 0], title='line plot') # doctest: +SKIP
>>> arr.plot(ax=ax[0, 0], title='line plot') # doctest: +SKIP
<Axes: title={'center': 'line plot'}, xlabel='year'>
>>> # bar plot with stacked values in the top right corner (0, 1)
>>> arr.plot.bar(ax=ax[0, 1], stacked=True, title='stacked bar plot') # doctest: +SKIP
>>> arr.plot.bar(ax=ax[0, 1], stack='gender', title='stacked bar plot') # doctest: +SKIP
<Axes: title={'center': 'stacked bar plot'}, xlabel='year'>
>>> # area plot in the bottom left corner (1, 0)
>>> arr.plot.area(ax=ax[1, 0], title='area plot') # doctest: +SKIP
>>> arr.plot.area(ax=ax[1, 0], title='area plot') # doctest: +SKIP
<Axes: title={'center': 'area plot'}, xlabel='year'>
>>> # scatter plot in the bottom right corner (1, 1), using the year as color
>>> # index and a specific colormap
>>> arr.plot.scatter(ax=ax[1, 1], x='M', y='F', c=arr.year, colormap='viridis',
... title='scatter plot') # doctest: +SKIP
>>> plt.show() # doctest: +SKIP
... title='scatter plot') # doctest: +SKIP
<Axes: title={'center': 'scatter plot'}, xlabel='M', ylabel='F'>
>>> plt.show() # doctest: +SKIP
"""
return PlotObject(self)

Expand Down
Loading
Loading