Metadata-Version: 2.1
Name: legendkit
Version: 0.1.3
Summary: Legend creating and manipulation with ease for matplotlib
Home-page: https://github.com/Mr-Milk/legendkit
Author-email: yb97643@um.edu.mo
License: MIT
Description: <p align="center">
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/legendkit-project.svg">
        </p>
        
        ![pypi version](https://img.shields.io/pypi/v/legendkit?color=blue&logo=python&logoColor=white&style=flat-square)
        
        When you want to create or adjust the legend in matplotlib, things can get dirty. 
        LegendKit may solve your headache.
        
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/showcase.svg">
        
        ## Features
        
        - Easy title placement and alignment
        - Layout for multiple legends
        - Easy colorbar
        
        ## Installation
        
        ```shell
        pip install legendkit
        ```
        
        ## Usage
        
        Any parameters you can use in legend or colorbar in matplotlib can 
        also be used here.
        
        ### Use it as the same old day
        
        First create a plot
        
        Usually, this is how you create the legend, the long title looks bad when it place at the center.
        But you can do nothing about it.
        
        ```python
        import numpy as np
        import matplotlib.pyplot as plt
        
        x = np.arange(0, 10, 0.1)
        plt.plot(x, np.sin(x), color="r", label="sin")
        plt.plot(x, np.sin(x), color="r", label="cos")
        plt.legend(title="Trigonometry Functions")
        ```
        
        With legendkit, things are easy, replace the default legend creation
        ```python
        from legendkit import legend
        # plt.legend(title="Trigonometry Functions")
        legend(title="Trigonometry Functions", title_align="left")
        ```
        
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/example1.svg">
        
        You can even create legend like this
        ```python
        legend(title="Trigonometry Functions", title_pos="left", ncol=2)
        ```
        
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/example1-2.svg" width="300">
        
        
        ### Create Colorbar
        
        ```python
        from legendkit import Colorbar, EllipseColorbar
        
        Colorbar(vmin=0, vmax=10, title="Colorbar", title_align="left")
        EllipseColorbar(vmin=0, vmax=10, title="Ellipse Colorbar", title_align="left")
        ```
        
        ### Using preset legend
        
        ```python
        import matplotlib.pyplot as plt
        from legendkit import CatLegend, SizeLegend
        
        _, ax = plt.subplots()
        CatLegend(["r", "g", "b"], ["Item 1", "Item 2", "Item 3"])
        SizeLegend([i for i in range(101)])
        ```
        
        ### Create a custom legend
        
        If you want to create a custom legend, it's pretty easy to do it. Simple use an array to define it.
        
        ```python
        from legendkit import legend
        
        legend(legend_items=[
            # (handle, label, config)
            ('square', 'Item 1', {'color': '#01949A'}),
            ('circle', 'Item 2', {'facecolor': '#004369', 
                                  'edgecolor': '#DB1F48', 
                                  'linewidth': 0.5}),
            ('rect', 'Item 3', {'color': '#E5DDC8'}),
            # Or you can have no config at all
            ('line', 'Item 4'),
        ])
        
        ```
        
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/example2.svg">
        
        Or you can use matplotlib legend handlers for richer definition.
        
        LegendKit provides you with some predefined handlers to use out of the box.
        
        - The `SquareItem` will ensure square shape not matter how handle sizes are changed
        - The `RectItem` will ensure the rectangle shape even when handle sizes are the same
        - The `LineItem` is just a proxy to `Line2D`
        
        ```python
        from legendkit import legend
        from legendkit.handles import SquareItem, CircleItem, RectItem, LineItem
        from matplotlib.lines import Line2D
        
        legend(
            handles=[SquareItem(), CircleItem(), RectItem(), LineItem(), Line2D([], [])], 
            labels=['Square', 'Circle', 'Rect', 'Line', 'Matplotlib Line'
        ])
        
        ```
        
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/example2-2.svg">
        
        If you want to use highly customized element as entry, 
        please refer to [here](https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html#implementing-a-custom-legend-handler)
        
        
        ### Multiple legends layout
        
        Sometimes you may want to group few legends together
        
        - `vstack` is used to stack legends vertically
        - `hstack` is used to stack legends horizontally
        
        ```python
        import matplotlib.pyplot as plt
        from legendkit import legend
        from legendkit.layout import vstack, hstack
        
        _, ax = plt.subplots()
        
        legend1 = legend(legend_items=[
            ('circle', 'The Moon', {'color': '#41729F'}),
        ], title="Earth's Moon")
        
        legend2 = legend(legend_items=[
            ('circle', 'Deimos', {'color': '#3D550C'}),
            ('circle', 'Phobos', {'color': '#81B622'}),
        ], title="Mars' Moons")
        
        legend3 = legend(legend_items=[
            ('circle', 'Io', {'color': '#FB4570'}),
            ('circle', 'Europa', {'color': '#FB6B90'}),
            ('circle', 'Ganymede', {'color': '#FB8DA0'}),
            ('circle', 'Callisto', {'color': '#EFEBE0'}),
        ], title="Moons of Jupyter")
        
        legends = hstack([legend1, legend2, legend3], title="Moons in solar systems", spacing=10, frameon=True)
        ax.add_artist(legends)  # Make sure you add it to the axes, or it won't be rendered
        
        ```
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/example3.svg">
        
        
        ### Grid layout with nested stack
        
        You can create nested stack by stacking other stacks.
        
        ```python
        from legendkit.layout import vstack, hstack
        
        s1 = vstack([])
        s2 = vstack([])
        
        final = hstack([s1, s2])
        ```
        
        ## Understand layout in matplotlib legend
        
        If you are familiar with css flexbox model, this is similar to how legend is layout internally in 
        matplotlib. 
        
        A matplotlib legend have at least two parts, the handle and the label.
        
        - handle: The graphic to represent the item in the plot.
        - label: The text for the item.
        
        ### Parameters to control the layout
        
        The units used in the layout system is the same as font size.
        
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/handle_label_illustration.png" width="400">
        
        
        #### Control the handle
        
        - **handleheight**: The height of the handle.
        - **handlelength**: The length of the handle.
        
        #### Control the handle and the label:
        
        - **handletextpad**: the distance between the handle and the label.
        
        <img src="https://raw.githubusercontent.com/Mr-Milk/legendkit/main/images/layout_padding_illustration.png" width="1400">
        
        #### Control between different items:
        
        - **labelspacing**: This control the distance between different legend items, 
           it also controls the distance between title and items.
        - **columnspacing**: The distance between multiple columns of items.
        
        #### Control the legend outer frame:
        
        - **frameon**: Toggle the on/off of the outer frame.
        - **borderpad**: The distance between the actual legend and the outer frame, apply for both x and y direction.
        - **borderaxespad**: The distance between the axes and the legend.
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Framework :: Matplotlib
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.7
Description-Content-Type: text/markdown
