k1lib.viz module

class k1lib.viz.SliceablePlot(plotF: Callable[[slice], None], slices: Union[slice, List[slice]] = slice(None, None, None), plotDecorators: List[k1lib.viz._PlotDecorator] = [], docs='')[source]

This is a plot that is “sliceable”, meaning you can focus into a particular region of the plot quickly. A minimal example looks something like this:

import numpy as np, matplotlib.pyplot as plt, k1lib
x = np.linspace(-2, 2, 100)

def normalF():
    plt.plot(x, x**2)

@k1lib.viz.SliceablePlot.decorate
def plotF(_slice):
    plt.plot(x[_slice], (x**2)[_slice])

plotF()[70:] # plots x^2 equation with x in [0.8, 2]

So, normalF plots the equation \(x^2\) with x going from -2 to 2. You can convert this into a SliceablePlot by adding a term of type slice to the args, and decorate with decorate(). Now, every time you slice the SliceablePlot with a specific range, plotF will receive it.

How intuitive everything is depends on how you slice your data. [70:] results in x in [0.8, 2] is rather unintuitive. You can change it into something like this:

@k1lib.viz.SliceablePlot.decorate
def niceF(_slice):
    n = 100; r = k1lib.Range(-2, 2)
    x = np.linspace(*r, n)
    _slice = r.toRange(_k1lib.Range(n), r.bound(_slice)).slice_
    plt.plot(x[_slice], (x**2)[_slice])

niceF()[0.3:0.7] # plots x^2 equation with x in [0.3, 0.7]
niceF()[0.3:] # plots x^2 equation with x in [0.3, 2]

The idea is to just take the input slice, put some bounds on its parts, then convert that slice from [-2, 2] to [0, 100]. Check out k1lib.Range if it’s not obvious how this works.

A really cool feature of SliceablePlot looks like this:

niceF().legend(["A"])[-1:].grid(True).yscale("log")

This will plot \(x^2\) with range in [-1, 2] with a nice grid, and with y axis’s scale set to log. Essentially, undefined method calls on a SliceablePlot will translate into plt calls. So the above is roughly equivalent to this:

x = np.linspace(-2, 2, 100)
plt.plot(x, x**2)
plt.legend(["A"])
plt.grid(True)
plt.yscale("log")
_images/SliceablePlot.png

This works even if you have multiple axes inside your figure. It’s wonderful, isn’t it?

static decorate(f)[source]

Decorates a plotting function so that it becomes a SliceablePlot.

class k1lib.viz.Carousel[source]
__init__()[source]

Creates a new Carousel. You can then add images and whatnot. Will even work even when you export the notebook as html. Example:

import numpy as np, matplotlib.pyplot as plt, k1lib
c = k1lib.viz.Carousel()
x = np.linspace(-2, 2); plt.plot(x, x ** 2); c.savePlt()
x = np.linspace(-1, 3); plt.plot(x, x ** 2); c.savePlt()
c # displays in notebook cell
save(f: Callable[[_io.BytesIO], None])[source]

Generic image save function. Treat io.BytesIO as if it’s a file when you’re doing this:

with open("file.txt") as f:
    pass # "f" is similar to io.BytesIO

So, you can do stuff like:

import matplotlib.pyplot as plt, numpy as np
x = np.linspace(-2, 2)
plt.plot(x, x**2)
c = k1lib.viz.Carousel()
c.save(lambda io: plt.savefig(io, format="png"))
Parameters

f – lambda that provides a io.BytesIO for you to write to

savePlt()[source]

Saves current plot from matplotlib

savePIL(image)[source]

Saves a PIL image

k1lib.viz.plotSegments(x: List[float], y: List[float], states: List[int], colors: Optional[List[str]] = None)[source]

Plots a line graph, with multiple segments with different colors.

Parameters
  • x – (nullable) list of x coordinate at each point

  • y – list of y coordinates at each point

  • states – list of color at each point

  • colors – string colors to display for each states

Idea is, you have a normal line graph, but you want to color parts of the graph red, other parts blue. Then, you can pass a “state” array, with the same length as your data, filled with ints, like this:

y = np.array([ 460800,  921600,  921600, 1445888, 1970176, 1970176, 2301952,
       2633728, 2633728, 3043328, 3452928, 3452928, 3457024, 3461120,
       3463680, 3463680, 3470336, 3470336, 3467776, 3869184, 3865088,
       3865088, 3046400, 2972672, 2972672, 2309632, 2504192, 2504192,
       1456128, 1393664, 1393664,  472576])
s = np.array([1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       1, 0, 0, 1, 0, 0, 1, 0, 0, 1])
plotSegments(None, y, s, colors=["tab:blue", "tab:red"])
_images/plotSegments.png