k1lib.viz module

This module is for nice visualization tools. This is exposed automatically with:

from k1lib.imports import *
viz.mask # exposed
class k1lib.viz.SliceablePlot(plotF: Callable[[slice], None], slices: Union[slice, List[slice]] = slice(None, None, None), plotDecorators: List[_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])
# this works without a decorator too btw: k1lib.viz.SliceablePlot(niceF)

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.

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.

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
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 (matplotlib color strings) to display for each states

class k1lib.viz.Carousel(searchMode: int = 0)[source]
__init__(searchMode: int = 0)[source]

Creates a new Carousel that can flip through a list of images/html. Will even work even when you export the notebook as html. Example:

x = np.linspace(-2, 2); plt.plot(x, x ** 2); im1 = plt.gcf() | toImg()
x = np.linspace(-1, 3); plt.plot(x, x ** 2); im2 - plt.gcf() | toImg()
im3 = "<h1>abc</h1><div>Some content</div>" # can add html
[im1, im2, im3] | viz.Carousel() # displays in notebook cell
_images/carousel.png

There’s also a builtin search functionality that works like this:

[
    "<h1>abc</h1><div>Some content 1</div>",
    "<h1>def</h1><div>Some other content 2</div>",
    "<h1>ghi</h1><div>Another content 3</div>",
] | Carousel(searchMode=1)

[
    ["<h1>abc</h1>", "<div>Some content 1</div>"],
    ["<h1>def</h1>", "<div>Some other content 2</div>"],
    ["<h1>ghi</h1>", "<div>Another content 3</div>"],
] | Carousel(searchMode=2)

The first mode will search for some text inside the html content. The second mode will search inside the title only, that means it’s expecting to receive Iterator[title, html/img]

Parameters
  • imgs – List of initial images. Can add more images later on by using __ror__()

  • searchMode – 0 for no search, accepts Iterator[html/img], 1 for search content, accepts Iterator[html/img], 2 for search title, accepts Iterator[title, html/img]

__ror__(it)[source]
class k1lib.viz.Toggle[source]
__init__()[source]

Button to toggle whether the content is displayed or not. Useful if the html content is very big in size. Example:

x = np.linspace(-2, 2); plt.plot(x, x ** 2)
plt.gcf() | toImg() | toHtml() | viz.Toggle()

This will plot a graph, then create a button where you can toggle the image’s visibility

__ror__(it)[source]
class k1lib.viz.ToggleImage[source]

This function is sort of legacy. It’s just img | toHtml() | viz.Toggle() really

class k1lib.viz.Scroll(height=300)[source]
__init__(height=300)[source]

Creates a new preview html component. If content is too long, then it will only show the first 500px, then have a button to expand and view the rest. Example:

x = np.linspace(-2, 2); plt.plot(x, x ** 2)
plt.gcf() | toImg() | toHtml() | viz.Scroll()

This will plot a preview of a graph :param height: height of the parent container

__ror__(it)[source]
k1lib.viz.confusionMatrix(matrix: Tensor, categories: Optional[List[str]] = None, **kwargs)[source]

Plots a confusion matrix. Example:

k1lib.viz.confusionMatrix(torch.rand(5, 5), ["a", "b", "c", "d", "e"])
_images/confusionMatrix.png
Parameters
  • matrix – 2d matrix of shape (n, n)

  • categories – list of string categories

  • kwargs – keyword args passed into plt.figure()

k1lib.viz.FAnim(fig, f, frames, *args, **kwargs)[source]

Matplotlib function animation, 60fps. Example:

# line below so that the animation is displayed in the notebook. Included in :mod:`k1lib.imports` already, so you don't really have to do this!
plt.rcParams["animation.html"] = "jshtml"
x = np.linspace(-2, 2); y = x**2
fig, ax = plt.subplots()
plt.close() # close cause it'll display 1 animation, 1 static if we don't do this
def f(frame):
    ax.clear()
    ax.set_ylim(0, 4); ax.set_xlim(-2, 2)
    ax.plot(x[:frame], y[:frame])
k1lib.FAnim(fig, f, len(x)) # plays animation in cell
Parameters
  • fig – figure object from plt.figure(…) command

  • f – function that accepts 1 frame from frames.

  • frames – number of frames, or iterator, to pass into function

k1lib.viz.mask(img: Tensor, act: Tensor) Tensor[source]

Shows which part of the image the network is focusing on.

Parameters
  • img – the image, expected to have dimension of (3, h, w)

  • act – the activation, expected to have dimension of (x, y), and with elements from 0 to 1.