Skip to main content

Unified API and style for Python plotting libraries

Project description


python license jupyter

Unified API and style for Python plotting libraries.

Usage

plotly matplotlib
import numpy as np
import uplt

x = np.linspace(0, np.pi*4, num=100)
phi = np.pi/4

fig = uplt.figure('plotly')
fig.plot(x, np.sin(x - 0*phi), name='#1')
fig.plot(x, np.sin(x - 1*phi), name='#2')
fig.plot(x, np.sin(x - 2*phi), name='#3')
fig.plot(x, np.sin(x - 3*phi), name='#4')
fig.xlabel('X').ylabel('Y')
fig.legend().show()
import numpy as np
import uplt

x = np.linspace(0, np.pi*4, num=100)
phi = np.pi/4

fig = uplt.figure('matplot')
fig.plot(x, np.sin(x - 0*phi), name='#1')
fig.plot(x, np.sin(x - 1*phi), name='#2')
fig.plot(x, np.sin(x - 2*phi), name='#3')
fig.plot(x, np.sin(x - 3*phi), name='#4')
fig.xlabel('X').ylabel('Y')
fig.legend().show()

💡 See gallery for more examples.

💡 The uplot alias is available and can be used interchangeably with uplt.

Install

Recent stable version (without any plotting library):

pip install uplt-py

To automatically install all optional dependencies (matplotlib, plotly, ...):

pip install "uplt-py[all]"

If you need only matplotlib support:

pip install "uplt-py[matplot]"

💡 Replace [matplot] with [plotly] for plotly-only installation

Plotting Libs - Pros & Cons

Matplotlib

🟢 Highly configurable.
🟢 Good documentation and a lot of ready-to-use recipes (e.g. on StackOverflow).
🟡 Common API (MATLAB legacy).

🔴 Limited interactivity (especially for Jupyter).
🔴 API, behavior and parameter names are inconsistent (e.g. plt.xlim and axis.set_xlim).
🔴 Slow and limited 3D rendering.

Plotly

🟢 Very good interactivity.
🟢 Native compatibility with Jupyter.
🟢 Possibility to save interactive plot (html-file).
🟢 Fast and interactive 3D plot.

🔴 Not well documented (a lot of parameters, small amount of examples).
🔴 High memory consumption (limited number of plots in Jupyter).
🔴 Some expected API functions are missing (e.g. imshow).
🔴 3D and 2D axis parameters are not unified (e.g. layout.xaxis doesn't work for 3D).

Functions

Function Description
plot(x, y, z)
plot(obj)
Plot 2D or 3D line.
Line plot for custom class (supported by a plugin).
scatter(x, y, z)
scatter(obj)
Scatter plot for 2D or 3D data points.
Scatter plot for custom class (supported by a plugin).
surface3d(x, y, z) Plot a surface in 3D space where the color scale corresponds to the z-values.
bar(x, y) Create a bar plot.
imshow(image) Display an image.
hline(y)
vline(x)
Plot horizontal or vertical line. 2D only
title(text) Set the title of the figure.
legend(show) Show or hide the legend on the figure.
grid(show) Show or hide the grid on the figure.
xlabel(text)
ylabel(text)
zlabel(text)
Set the label for the x, y, z-axis.
xlim(min, max)
ylim(min, max)
zlim(min, max)
Set limits for the x, y, z-axis.
xscale()
yscale()
Set scale for the x, y-axis: 'linear' or 'log'.
current_color()
scroll_color(count)
reset_color()
Get the color which will be used for the next plot.
Scroll a list of predefined colors for plots.
Set the current color to the start of the list.
axis_aspect(mode) Set the aspect ratio of the axis.
as_image() Get the figure as a NumPy array.
save(filename) Save the figure to a file.
close() Close the figure. Free allocated resources.
show(block) Display the figure.

Extending

Plugin

The plugin system allows extending uplt for visualizing custom objects. For example, the DataFrame plugin enables this code:

import uplt
import pandas as pd

car_crashes = pd.read_csv(
    'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/car_crashes.csv'
)

fig = uplt.figure()
fig.plot(car_crashes[['total', 'speeding', 'alcohol', 'no_previous']])
fig.show()

To implement the plugin, you can follow this structure:

import numpy as np
import pandas as pd

import uplt.plugin as plugin


class DataFramePlugin(plugin.IPlotPlugin):

    def extract_data(self, obj: pd.DataFrame) -> list[plugin.PlotData]:
        data = []
        for name in obj.columns:
            if not np.issubdtype(obj.dtypes[name], np.number): continue
            y = obj[name].values
            x = np.arange(len(y))
            data.append(plugin.PlotData(x=x, y=y, name=name.replace('_', ' ').title()))
        return data

plugin.register(pd.DataFrame, handler=DataFramePlugin())

💡 Check test/plugin.py for a more advanced plugin example.

Engine

Adding a new plotting library is straightforward. Implement two interfaces IPlotEngine and IFigure:

import uplt
from uplt import IPlotEngine, IFigure

class MyEngine(IPlotEngine):
    ...
    def figure(self, ...) -> MyFigure: ...

class MyFigure(IFigure):
    def plot(self, ...): ...
    def scatter(self, ...): ...
    ...

# register the engine
uplt.engine.register(MyEngine(), name='test')

Then use it in the regular way:

import uplt

fig = uplt.figure(engine='test')
fig.plot(...)
fig.show()

Dependencies

  • Python ≥ 3.10
  • NumPy ≥ 1.21 v2.0 supported
  • pillow ≥ 10.3

Optional

  • matplotlib ≥ 3.7
  • plotly ≥ 5.17

License

This software is licensed under the BSD-3-Clause license. See the LICENSE file for details.

TODO

Check the plan for new features here.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uplt-py-0.8.2.tar.gz (2.9 MB view details)

Uploaded Source

File details

Details for the file uplt-py-0.8.2.tar.gz.

File metadata

  • Download URL: uplt-py-0.8.2.tar.gz
  • Upload date:
  • Size: 2.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.13

File hashes

Hashes for uplt-py-0.8.2.tar.gz
Algorithm Hash digest
SHA256 1e5d8ea52b71add61f77da2da1527971a2f20fc61a60797e85fe67e02ede6d8b
MD5 a3d35d3f15600be073bb3de21b3569a0
BLAKE2b-256 0069dead50ed88e6a8b312eb04cc73e15369ad6dd8343943c7d80fc66c42a5fe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page