cdxcore.dynaplot#

Tools for dynamic plotting in Jupyer/IPython.

The aim of the toolkit is making it easier to develop animated visualization with matplotlib, for example during training with machine learing kits such as pyTorch.

This has been tested with Anaconda’s JupyterHub and %matplotlib inline.

Overview#

It also makes the creation of subplots more streamlined.

The package now contains a lazy method to manage updates to graphs (animations). This is implemented as follows:

Here is an example of animated line plots using cdxcore.dynaplot.DynaFig.store():

%matplotlib inline
import numpy as np
from cdxcore.dynaplot import figure   # 'figure' is an alias for DynaFig

x  = np.linspace(0,1,100)
pm = 0.2

fig = figure(col_size=10)
ax  = fig.add_subplot()
ax2 = fig.add_subplot()
ax2.sharey(ax)
store = fig.store()

fig.render()

import time
for i in range(5):
    y = np.random.random(size=(100,))
    ax.set_title(f"Test {i}")
    ax2.set_title(f"Test {i}")

    store.remove() # delete all previously stored elements
    store += ax.plot(x,y,":", label=f"data {i}")
    store += ax2.plot(x,y,"-",color="red", label=f"data {i}")
    store += ax2.fill_between( x, y-pm, y+pm, color="blue", alpha=0.2 )
    store += ax.legend()

    fig.render()
    time.sleep(0.5)
fig.close()
../../_images/dynaplot.gif

This example shows the use of store with different elements.

Here is an example with animated 3D plots, calling matplotlib.axes.Axes.remove() manually:

%matplotlib inline
import numpy as np
from cdxcore.dynaplot import figure   # 'figure' is an alias for DynaFig
import math

x = np.linspace(0.,2.*math.pi,51)
y = x

fig  = figure()
ax1  = fig.add_subplot(projection='3d')
ax2  = fig.add_subplot(projection='3d')
ax1.set_xlim(0.,2.*math.pi)
ax1.set_ylim(0.,2.*math.pi)
ax1.set_zlim(-2,+2)
ax1.set_title("Color specified")
ax2.set_xlim(0.,2.*math.pi)
ax2.set_ylim(0.,2.*math.pi)
ax2.set_zlim(-2,+2)
ax2.set_title("Color not specified")
fig.render()
r1 = None
r2 = None
import time
for i in range(50):
    time.sleep(0.01)
    z = np.cos( float(i)/10.+x )+np.sin( float(i)/2.+y )
    if not r1 is None: r1.remove()
    if not r2 is None: r2.remove()
    r1 = ax1.scatter( x,y,z, color="blue" )
    r2 = ax2.scatter( 2.*math.pi-x,math.pi*(1.+np.sin( float(i)/2.+y )),z )
    fig.render()
fig.close()
print("/done")
../../_images/dynaplot3D.gif

The jupyter notebook contains a few more examples.

Simpler sub_plot#

The package lets you create sub plots without having to know the number of plots in advance. You have the following two main options when creating a new cdxcore.dynaplot.figure():

  • Define as usual figsize, and specify the number of columns. In this case the figure will arrange plots you add with cdxcore.dynaplot.DynaFig.add_subplot() iteratively with at most columns plots per row. add_subplot() will not need any additional positional arguments.

  • Instead, you can specify col_size, row_size, and columns: the first two define the size per subplot. Like before you then add your sub plots using cdxcore.dynaplot.DynaFig.add_subplot() without any additional positioning arguments.

    Assuming you add N subplots, then the overall figsize will be (col_size* (N%col_num),  row_size (N//col_num)).

When adding plots with cdxcore.dynaplot.DynaFig.add_subplot() you can make it skip to the first column in the next row, by calling cdxcore.dynaplot.DynaFig.next_row().

The example also shows that we can specify titles for subplots and figures easily:

%matplotlib inline
import numpy as np
from cdxcore.dynaplot import figure   # 'figure' is an alias for DynaFig

fig    = figure(title="Multi Graph", columns=4)
ref_ax = None
x = np.linspace(0,1,100)
for k in range(9):
    ax = fig.add_subplot(f"Test {k}")
    y = np.random.random(size=(100,1))
    ax.plot(x,y,":",color="red", label="data")
    ax.legend(loc="upper left")

    if not ref_ax is None:
        ax.sharey(ref_ax)
        ax.sharex(ref_ax)
    else:
        ref_ax = ax
fig.close()
../../_images/multi.gif

Grid Spec#

Another method to place plots is by explicitly positioning them using a matplotlib.gridspec.GridSpec. In line with the paradigm of delayed creation, use cdxcore.dynaplot.DynaFig.add_gridspec() to generate a deferred grid spec.

Example:

%matplotlib inline
from cdxcore.dynaplot import figure
import numpy as np
x = np.linspace(-2.,+2,101)
y = np.tanh(x)
fig = figure("Grid Spec Example", figsize=(10,5))
gs  = fig.add_gridspec(2,2)

ax = fig.add_subplot("1", spec_pos=gs[0,0] )
ax.plot(x,y)
ax = fig.add_subplot("2", spec_pos=gs[:,1] )
ax.plot(x,y)
ax = fig.add_subplot("3", spec_pos=gs[1,0] )
ax.plot(x,y)
fig.close()
../../_images/gridspec.gif

Color Management#

Use cdxcore.dynaplot.color_css4(), cdxcore.dynaplot.color_base(), cdxcore.dynaplot.color_tableau(), cdxcore.dynaplot.color_xkcd() to return an i th element of the respective matplotlib color table. This simplifies using consistent colors accross different plots or when re-creating plots during an animation.

Example of using the same colors by order in two plots:

%matplotlib inline
import numpy as np
import math
import time
from cdxcore.dynaplot import figure, color_base   # 'figure' is an alias for DynaFig

x = np.linspace(0.,2.*math.pi,51)

fig = figure(fig_size=(14,6))
ax = fig.add_subplot("Sin")
store = fig.store()
# draw 10 lines in the first sub plot, and add a legend
for i in range(10):
    y = np.sin(x/(i+1))
    ax.plot( x, y, color=color_base(i), label=f"f(x/{i+1})" )
ax.legend(loc="lower right")

# draw 10 lines in the second sub plot.
# use the same colors for the same scaling of 'x'
ax = fig.add_subplot("Cos")

for i in range(10):
    z = np.cos(x/(i+1))
    store += ax.plot( x, z, color=color_base(i) )
fig.render()

# animiate, again with the same colors
for p in np.linspace(0.,4.,11,endpoint=False):
    time.sleep(0.1)
    store.clear() # alias for 'remove'
    for i in range(10):
        z = np.cos((x+p)/(i+1))
        store += ax.plot( x, z, color=color_base(i) )
    fig.render()

fig.close()
../../_images/colors.gif

Here is a view of the first 20 colors of the four supported maps:

../../_images/colormap.gif

The classes cdxcore.dynaplot.colors_css4, cdxcore.dynaplot.colors_base, cdxcore.dynaplot.colors_tableau, cdxcore.dynaplot.colors_xkcd are generators for the same colors.

Known Issues#

Some users reported that the package does not work in some versions of Jupyter, in particular with VSCode. In this case, please try changing the draw_mode parameter when calling cdxcore.dynaplot.figure().

Import#

fronm cdxcore.dynaplot import figure

Documentation#

Module Attributes

color_names

List of available colors names.

Functions

color(i[, table])

Returns a color with a given index to allow consistent colouring.

color_base(i)

Returns the i'th base color:

color_css4(i)

Returns the i'th css4 color:

color_tableau(i)

Returns the i'th tableau color:

color_xkcd(i)

Returns the i th xkcd color.

colors([table])

Returns a generator for the colors of the specified table.

colors_base()

Iterator for "base" matplotlib colors:

colors_css4()

Iterator for "css4" matplotlib colors:

colors_tableau()

Iterator for ""tableau"" matplotlib colors:"

colors_xkcd()

Iterator for xkcd.

figure([title, row_size, col_size, ...])

Creates a dynamic figure of type cdxcore.dynaplot.DynaFig.

store()

Creates a cdxcore.dynaplot.FigStore which can be used to dynamically update a figure.

Classes

DynaAx(*, fig_id, fig_list, row, col, ...)

Deferred wrapper around a matplotlib.pyplot.axis objects returned by cdxcore.dynaplot.DynaFig.add_subplot() or similar.

DynaFig([title, row_size, col_size, ...])

Deferred wrapper around matplotlib.pyplot.figure.

FigStore()

Utility class to manage dynamic content by removing old graphical elements (instead of using element-specifc update).

MODE()

How to draw graphs.

class cdxcore.dynaplot.DynaAx(*, fig_id, fig_list, row, col, spec_pos, rect, title, projection, kwargs)[source]#

Bases: _DynaDeferred

Deferred wrapper around a matplotlib.pyplot.axis objects returned by cdxcore.dynaplot.DynaFig.add_subplot() or similar.

You should not need to know that this object is not actually a matplotlib.pyplot.axis. If you receive error messages which you do not understand, please contact the authors of this module.

Attributes:
deferred_dependants

Retrieve list of dependant cdxcore.deferred.Deferred objects.

deferred_info

Text description of the current action.

deferred_result

Returns the result of the deferred action, if available.

deferred_result_or_self

Returns the result of the deferred action, if available, or self.

deferred_source_dependants

Retrieve list of dependant cdxcore.deferred.Deferred objects at the level of the original parent source.

deferred_sources

Retrieve a dictionary with information on all top-level sources this deferred action depends on.

deferred_sources_names

Retrieve a list of names of all top-level sources this deferred action depends on.

deferred_was_resolved

Whether the underlying operation has already been resolved.

Methods

Create(info)

Create top level element.

__call__(*args, **kwargs)

Create __call__ action

auto_limits(low_quantile, high_quantile[, ...])

Add automatic limits using cdxcore.dynalimits.AutoLimits.

deferred_create_action(**kwargsa)

Creates a deferred action created during another deferred action.

deferred_print_dependency_tree([verbose, ...])

Prints the dependency tree recorded by this object and its descendants.

deferred_resolve(element[, verbose])

Resolve the top level deferred element.

plot(*args[, scalex, scaley, data])

Wrapper around matplotlib.axes.plot().

remove()

Equivalent of matplotlib.axes.Axes.remove(): removes this axis from the underlying figure.

set_auto_lims(*args, **kwargs)

Apply cdxcore.dynalimits.AutoLimits for this axis.

auto_limits(low_quantile, high_quantile, min_length=10, lookback=None)[source]#

Add automatic limits using cdxcore.dynalimits.AutoLimits.

Parameters:
low_quantilefloat

Lower quantile to use for computing a ‘min’ y value. Set to 0 to use the actual ‘min’.

high_quantilefloat

Higher quantile to use for computing a ‘min’ y value. Set to 1 to use the actual ‘max’.

min_lengthint, optional

Minimum length data must have to use numpy.quantile(). If less data is presented, use min/max, respectively. Default is 10.

lookbackint

How many steps to lookback for any calculation. None to use all steps.

plot(*args, scalex=True, scaley=True, data=None, **kwargs)[source]#

Wrapper around matplotlib.axes.plot().

This function wrapper does not support the data interface of matplotlib.axes.plot().

If automatic limits are not used, this is a wrapper with deferred pass-through. If automatic limits are used, then this function will update the underlying automated limits accordingly.

Parameters:
args, scalex, scaley, data, kwargs

See matplotlib.axes.plot().

Returns:
plotDeferred

This function will return a wrapper around an actual axis which is used to defer actioning any subsequent calls to until cdxcore.dynaplot.DynaFig.render() is called.

You should not need to consider this. If you encounter problems in usability please contact the authors.

remove()[source]#

Equivalent of matplotlib.axes.Axes.remove(): removes this axis from the underlying figure. Note that this will not trigger a removal from the actual visualization until cdxcore.dynaplot.DynaFig.render() is called.

set_auto_lims(*args, **kwargs)[source]#

Apply cdxcore.dynalimits.AutoLimits for this axis. See cdxcore.dynalimits.AutoLimits.set_lims for parameter description.

class cdxcore.dynaplot.DynaFig(title=None, *, row_size=5, col_size=4, fig_size=None, columns=5, tight=True, draw_mode=1, **fig_kwargs)[source]#

Bases: _DynaDeferred

Deferred wrapper around matplotlib.pyplot.figure.

Wraps matplotlib matplotlib.pyplot.figure. Provides a simple cdxcore.dynaplot.DynaFig.add_subplot() without the need to pre-specify axes positions as is common for matplotlib.

See cdxcore.dynaplot.figure() for more information.

Attributes:
deferred_dependants

Retrieve list of dependant cdxcore.deferred.Deferred objects.

deferred_info

Text description of the current action.

deferred_result

Returns the result of the deferred action, if available.

deferred_result_or_self

Returns the result of the deferred action, if available, or self.

deferred_source_dependants

Retrieve list of dependant cdxcore.deferred.Deferred objects at the level of the original parent source.

deferred_sources

Retrieve a dictionary with information on all top-level sources this deferred action depends on.

deferred_sources_names

Retrieve a list of names of all top-level sources this deferred action depends on.

deferred_was_resolved

Whether the underlying operation has already been resolved.

Methods

Create(info)

Create top level element.

__call__(*args, **kwargs)

Create __call__ action

add_axes(rect[, title, projection])

Add a freely placed sub plot.

add_gridspec([ncols, nrows])

Wrapper for matplotlib.figure.Figure.add_gridspec(), returning a defered GridSpec.

add_plot([title, new_row, spec_pos, projection])

Adds a subplot.

add_subplot([title, new_row, spec_pos, ...])

Adds a subplot.

close([render, clear])

Closes the figure.

deferred_create_action(**kwargsa)

Creates a deferred action created during another deferred action.

deferred_print_dependency_tree([verbose, ...])

Prints the dependency tree recorded by this object and its descendants.

deferred_resolve(element[, verbose])

Resolve the top level deferred element.

delaxes(ax, *[, render])

Equivalent of matplotlib.figure.Figure.delaxes(), but this function can also take a list.

get_axes()

Equivalent to self.axes

next_row()

Skip to next row.

remove_all_axes(*[, render])

Calles cdxcore.dynalot.DynaAx.remove() for all axes

render([draw])

Draw all axes.

savefig(fname[, silent_close])

Saves the figure to a file.

store()

Create a FigStore().

to_bytes([silent_close])

Convert figure to a byte stream.

add_axes(rect, title=None, *, projection=None, **kwargs)[source]#

Add a freely placed sub plot.

Like matplotlib.figure.Figure.add_axes() this function allows placing a plot at a given position within a figure using rect. This plot may overlay previously generated plots.

This function can be called after the cdxcore.dynaplot.DynaFig.close() was called.

Note that using this function with a tight figure will result in a UserWarning. Use tight=False when constructing your figure to avoid this warning.

Parameters:
recttuple (left, bottom, width, height)

The dimensions (left, bottom, width, height) of the new plot. All quantities are in fractions of figure width and height.

titlestr, optional

Title for the plot, or None for no plot.

projectionstr, optional

What projection to use. The default None matches the default choice for matplotlib.figure.Figure.add_axes()

args, kwargs

keyword arguments to be passed to matplotlib.figure.Figure.add_axes().

add_gridspec(ncols=1, nrows=1, **kwargs)[source]#

Wrapper for matplotlib.figure.Figure.add_gridspec(), returning a defered GridSpec.

add_plot(title=None, *, new_row=None, spec_pos=None, projection=None, **kwargs)#

Adds a subplot.

Compared to matplotlib.figure.Figure.add_subplot() this function does not require the tedious positioning arguments which are required when using matplotlib.figure.Figure.add_subplot(). This function also allows to directly specify a plot title.

Implementation Comment:

This function returns a wrapper which defers the creation of the actual sub plot until cdxcore.dynaplot.DynaFig.render() or cdxcore.dynaplot.DynaFig.close() is called. Thus this function cannot be called after cdxcore.dynaplot.DynaFig.render() was called as then the geometry of the plots is set. Use cdxcore.dynaplot.DynaFig.add_axes() to draw plots in any position.

Parameters:
titlestr, optional

Optional title for the plot.

new_rowbool, optional

Whether to force a new row and place this polt in the first column. Default is False.

spec_posoptional

Grid spec position, or None.

projectionstr, optional

What projection to use. The default None matches the default choice for matplotlib.figure.Figure.add_subplot()column. Default is False.

spec_posoptional

Grid spec position, or None.

projectionstr, optional

What projection to use. The default None matches the default choice for matplotlib.figure.Figure.add_subplot().

kwargsdict

other arguments to be passed to matplotlib’s matplotlib.figure.Figure.add_subplot().

add_subplot(title=None, *, new_row=None, spec_pos=None, projection=None, **kwargs)[source]#

Adds a subplot.

Compared to matplotlib.figure.Figure.add_subplot() this function does not require the tedious positioning arguments which are required when using matplotlib.figure.Figure.add_subplot(). This function also allows to directly specify a plot title.

Implementation Comment:

This function returns a wrapper which defers the creation of the actual sub plot until cdxcore.dynaplot.DynaFig.render() or cdxcore.dynaplot.DynaFig.close() is called. Thus this function cannot be called after cdxcore.dynaplot.DynaFig.render() was called as then the geometry of the plots is set. Use cdxcore.dynaplot.DynaFig.add_axes() to draw plots in any position.

Parameters:
titlestr, optional

Optional title for the plot.

new_rowbool, optional

Whether to force a new row and place this polt in the first column. Default is False.

spec_posoptional

Grid spec position, or None.

projectionstr, optional

What projection to use. The default None matches the default choice for matplotlib.figure.Figure.add_subplot().

kwargsdict

other arguments to be passed to matplotlib’s matplotlib.figure.Figure.add_subplot().

axes#

List of axes. Until; cdxcore.dynaplot.DynaFig.render() is called, these are cdxcore.dynaplot.DynaAx objects;

close(render=True, clear=False)[source]#

Closes the figure.

Call this to avoid a duplicate in jupyter output cells. By dault this function will call cdxcore.dynaplot.DynaFig,render() to draw the figure, and then close it.

Parameters:
renderbool, optional

If True`, the default, this function will call cdxcore.dynaplot.DynaFig,render() and therefore renders the figure before closing the figure.

clear

If True, all axes will be cleared. This is experimental. The default is False.

delaxes(ax, *, render=False)[source]#

Equivalent of matplotlib.figure.Figure.delaxes(), but this function can also take a list.

get_axes()[source]#

Equivalent to self.axes

grid_specs#

afterwards, these are matplotlib.pyplot.axis objects.

next_row()[source]#

Skip to next row.

The next plot generated by cdxcore.dynaplot.DynaFig.add_subplot() will appears in the first column of the next row.

remove_all_axes(*, render=False)[source]#

Calles cdxcore.dynalot.DynaAx.remove() for all axes

render(draw=True)[source]#

Draw all axes.

If this function does not display the plots you generated, review the draw_mode parameter provided to cdxcore.dynaplot.figure() or cdxcore.dynaplot.DynaFig(), respectively,

Once called, no further plots can be added, but the plots can be updated in place.

Parameters:
drawbool

If False, then the figure is created, but not drawn. You usually use False when planning to use cdxcore.dynaplot.DynaFig.savefig() or cdxcore.dynaplot..DynaFig.to_bytes().

savefig(fname, silent_close=True, **kwargs)[source]#

Saves the figure to a file.

Wrapper around matplotlib.pyplot.savefig(). Essentially, this function writes the figure to a file] rather than displaying itl.

Parameters:
fnamestr

filename or file-like object

silent_closebool

If True (the default), call cdxcore.dynaplot.DynaFig,close() once the figure was saved to disk. Unless the figure was drawn before, this means that the figure will not be displayed in jupyter, and subsequent activity is blocked.

kwargsdict

These arguments will be passed to matplotlib.pyplot.savefig().

static store()[source]#

Create a FigStore(). Such a store allows managing graphical elements (artists) dynamically.

to_bytes(silent_close=True)[source]#

Convert figure to a byte stream.

This stream can be used to generate a IPython image using:

from IPython.display import Image, display
bytes = fig.to_bytes()
image = Image(data=byes)
display(image)
Parameters:
silent_closebool, optional

If True, call cdxcore.dynaplot.DynaFig,close() after this genersating the byte streanm. Unless the figure was drawn before, this means that the figure will not be displayed in jupyter, and subsequent activity is blocked.

Returns:
imagebytes

Buyte stream of the image.

class cdxcore.dynaplot.FigStore[source]#

Bases: object

Utility class to manage dynamic content by removing old graphical elements (instead of using element-specifc update).

Allows implementing a fairly cheap dynamic pattern:

from cdxbasics.dynaplot import figure
import time as time

fig = figure()
ax = fig.add_subplot()
store = fig.store()

x = np.linspace(-2.,+2,21)

for i in range(10):
    store.remove()
    store += ax.plot( x, np.sin(x+float(i)) )
    fig.render()
    time.sleep(1)

fig.close()

As in the example above, the most convenient way to create a FigStore object is to call :meth:`cdxcore.dynaplot.DynaFig.store on your figure.

Methods

add(element)

Add an element to the store.

clear()

Removes all elements by calling their matplotlib.artist.Artist.remove() function.

remove()

Removes all elements by calling their matplotlib.artist.Artist.remove() function.

add(element)[source]#

Add an element to the store. The same operation is available using +=

Parameters:
elementmatplotlib.artist.Artist

Graphical matplot element derived from matplotlib.artist.Artist such as matplotlib.lines.Line2D; or a Collection of the above; or None.

Returns:
``self``Figstore

This way compound statements a.add(x).add(y).add(z) work.

clear()#

Removes all elements by calling their matplotlib.artist.Artist.remove() function. Handles any Collection of such elements is as well.

remove()[source]#

Removes all elements by calling their matplotlib.artist.Artist.remove() function. Handles any Collection of such elements is as well.

class cdxcore.dynaplot.MODE[source]#

Bases: object

How to draw graphs. The best mode depends on the output IPython implementation.

CANVAS_DRAW = 4#

Call matplotlib.pyplot.figure.canvas.draw().

CANVAS_IDLE = 2#

Call matplotlib.pyplot.figure.canvas.draw_idle().

HDISPLAY = 1#

Call IPython.display.display().

JUPYTER = 1#

Setting which works for Jupyter lab as far as we can tell.

PLT_SHOW = 128#

Call matplotlib.pyplot.show().

VSCODE = 129#

Setting which works for VSCode it seems. Feedback welome.

cdxcore.dynaplot.color(i, table='css4')[source]#

Returns a color with a given index to allow consistent colouring.

Parameters:
iint

Integer number. Colors will be rotated.

tablestr, optional

Which color table from matplotlib.colors() to use: “css4”, “base”, “tableau” or “xkcd”. Default is "css4".

Returns:
Color codestr
cdxcore.dynaplot.color_base(i)[source]#

Returns the i’th base color:

https://matplotlib.org/stable/_images/sphx_glr_named_colors_001_2_00x.png
cdxcore.dynaplot.color_css4(i)[source]#

Returns the i’th css4 color:

https://matplotlib.org/stable/_images/sphx_glr_named_colors_003_2_00x.png
cdxcore.dynaplot.color_names = ['css4', 'base', 'tableau', 'xkcd']#

List of available colors names.

cdxcore.dynaplot.color_tableau(i)[source]#

Returns the i’th tableau color:

https://matplotlib.org/stable/_images/sphx_glr_named_colors_002_2_00x.png
cdxcore.dynaplot.color_xkcd(i)[source]#

Returns the i th xkcd color.

cdxcore.dynaplot.colors(table='css4')[source]#

Returns a generator for the colors of the specified table.

Parameters:
tablestr, optional

Which color table from matplotlib.colors to use: "css4", "base", "tableau", or "xkcd". Default is "css4".

Returns:
Generator for colors.

Use next() or iterate.

cdxcore.dynaplot.colors_base()[source]#

Iterator for “base” matplotlib colors:

https://matplotlib.org/stable/_images/sphx_glr_named_colors_001_2_00x.png
cdxcore.dynaplot.colors_css4()[source]#

Iterator for “css4” matplotlib colors:

https://matplotlib.org/stable/_images/sphx_glr_named_colors_003_2_00x.png
cdxcore.dynaplot.colors_tableau()[source]#

Iterator for “”tableau”” matplotlib colors:”

https://matplotlib.org/stable/_images/sphx_glr_named_colors_002_2_00x.png
cdxcore.dynaplot.colors_xkcd()[source]#

Iterator for xkcd. matplotlib colors

cdxcore.dynaplot.figure(title=None, *, row_size=5, col_size=4, fig_size=None, columns=5, tight=True, draw_mode=1, **fig_kwargs)[source]#

Creates a dynamic figure of type cdxcore.dynaplot.DynaFig.

By default the fig_size of the underlying matplotlib.pyplot.figure will be derived from the number of plots vs cols, row_size and col_size as (col_size* (N%col_num),  row_size (N//col_num)).

If fig_size is specified then row_size and col_size are ignored.

Once the figure is constructed,

  1. Use cdxcore.dynaplot.DynaFig.add_subplot() to add plots (without the cumbersome need to know the number of plots in advance);

  2. Call cdxcore.dynaplot.DynaFig.render() to place those plots.

  3. Call cdxcore.dynaplot.DynaFig.close() to close the figure and avoid duplicate copies in Jupyter.

Examples:

Simply use cdxcore.dynaplot.DynaFig.add_subplot() without the matplotlib need to pre-specify axes positions:

from cdxcore.dynaplot import figure    
fig = dynaplot.figure("Two plots")
ax = fig.add_subplot("1")
ax.plot(x,y)
ax = fig.add_subplot("2")
ax.plot(x,y)
fig.render()

Here is an example using matplotlib.figure.Figure.add_gridspec():

from cdxcore.dynaplot import figure    
fig = dynaplot.figure()
gs  = fig.add_gridspec(2,2)
ax = fig.add_subplot( gs[:,0] )
ax.plot(x,y)
ax = fig.add_subplot( gs[:,1] )
ax.plot(x,y)
fig.render()

Important Functions:

The returned cdxcore.dynaplot.DynaFig will defer all other function calls to the figure object until cdxcore.dynaplot.DynaFig.render() or cdxcore.dynaplot.DynaFig.close() are called.

The following direct members are important for using the framework:

Parameters:
titlestr, optional

An optional title which will be passed to matplotlib.pyplot.suptitle().

fig_sizetuple[int], optional

By default the fig_size of the underlying matplotlib.pyplot.figure will be derived from the number of plots vs cols, row_size and col_size as (col_size* (N%col_num),  row_size (N//col_num)).

If fig_size is specified then row_size and col_size are ignored.

row_sizeint, optional

Size for a row for matplot lib. Default is 5. This is ignored if fig_size is specified.

col_sizeint, optional

Size for a column for matplot lib. Default is 4. This is ignored if fig_size is specified.

columnsint, optional

How many columns to use when cdxcore.dynaplot.DynaFig.add_subplot() is used. If omitted then the default is 5.

tightbool, optional

Short cut for matplotlib.figure.Figure.set_tight_layout(). The default is True.

Note that when tight is True and cdxcore.dynaplot.DynaFig.add_axes() is called a UserWarning is generated. Turn tight off to avoid this.

draw_modeint, optional

A combination of cdxcore.dynaplot.MODE flags on how to draw plots once they were rendered. The required function call differs by IPython platform. The default, cdxcore.dynaplot.MODE.JUPYTER draws well on Jupyter notebooks. For VSCode, you might need cdxcore.dynaplot.MODE.VSCODE.

fig_kwargs

Other matplotlib parameters for matplotlib.pyplot.figure() to create the figure.

Returns:
figure: cdxcore.dynaplot.DynaFig

A dynamic figure.

cdxcore.dynaplot.store()[source]#

Creates a cdxcore.dynaplot.FigStore which can be used to dynamically update a figure.