yade.plot module

Module containing utility functions for plotting inside yade. See examples/simple-scene/simple-scene-plot.py or examples/concrete/uniax.py for example of usage.

yade.plot.data = {'eps': [0.0001, 0.001, nan], 'force': [nan, nan, 1000.0], 'sigma': [12, nan, nan]}

Global dictionary containing all data values, common for all plots, in the form {‘name’:[value,…],…}. Data should be added using plot.addData function. All [value,…] columns have the same length, they are padded with NaN if unspecified.

yade.plot.plots = {'i': ('t',), 'i ': ('z1', 'v1')}

dictionary x-name -> (yspec,…), where yspec is either y-name or (y-name,’line-specification’). If (yspec,...) is None, then the plot has meaning of image, which will be taken from respective field of plot.imgData.

yade.plot.labels = {}

Dictionary converting names in data to human-readable names (TeX names, for instance); if a variable is not specified, it is left untranslated.

yade.plot.live = True

Enable/disable live plot updating.

yade.plot.liveInterval = 1

Interval for the live plot updating, in seconds.

yade.plot.setLiveForceAlwaysUpdate(forceLiveUpdate)[source]

The plot.liveInterval and plot.live control live refreshing of the plot during calculations. The refreshing is done in a separate thread, so that it does not interfere with calculations. Drawing the data will not work when at exactly the same time it is being updated in other thread. Use yade.plot.setLiveForceAlwaysUpdate(True) if you want calculations to PAUSE during the plot updates. This function returns current bool value of forced updates if the call was a success, otherwise it returns a str with explanation why it failed. It is guaranteed to work if simulation was paused with O.pause() call.

yade.plot.autozoom = True

Enable/disable automatic plot rezooming after data update. Sometimes rezooming must be skipped unless a call to plot.setLiveForceAlwaysUpdate forces it to work.

yade.plot.plot(noShow=False, subPlots=True)[source]

Do the actual plot, which is either shown on screen (and nothing is returned: if noShow is False - note that your yade compilation should present qt4 feature so that figures can be displayed) or, if noShow is True, returned as matplotlib’s Figure object or list of them.

You can use

>>> from yade import plot
>>> plot.resetData()
>>> plot.plots={'foo':('bar',)}
>>> plot.plot(noShow=True).savefig('someFile.pdf')
>>> import os
>>> os.path.exists('someFile.pdf')
True
>>> os.remove('someFile.pdf')

to save the figure to file automatically.

Note

For backwards compatibility reasons, noShow option will return list of figures for multiple figures but a single figure (rather than list with 1 element) if there is only 1 figure.

yade.plot.reset()[source]

Reset all plot-related variables (data, plots, labels)

yade.plot.resetData()[source]

Reset all plot data; keep plots and labels intact.

yade.plot.splitData()[source]

Make all plots discontinuous at this point (adds nan’s to all data fields)

yade.plot.reverseData()[source]

Reverse yade.plot.data order.

Useful for tension-compression test, where the initial (zero) state is loaded and, to make data continuous, last part must end in the zero state.

yade.plot.addData(*d_in, **kw)[source]

Add data from arguments name1=value1,name2=value2 to yade.plot.data. (the old {‘name1’:value1,’name2’:value2} is deprecated, but still supported)

New data will be padded with nan’s, unspecified data will be nan (nan’s don’t appear in graphs). This way, equal length of all data is assured so that they can be plotted one against any other.

>>> from yade import plot
>>> from pprint import pprint
>>> plot.resetData()
>>> plot.addData(a=1)
>>> plot.addData(b=2)
>>> plot.addData(a=3,b=4)
>>> pprint(plot.data)
{'a': [1, nan, 3], 'b': [nan, 2, 4]}

Some sequence types can be given to addData; they will be saved in synthesized columns for individual components.

>>> plot.resetData()
>>> plot.addData(c=Vector3(5,6,7),d=Matrix3(8,9,10, 11,12,13, 14,15,16))
>>> pprint(plot.data)
{'c_x': [5.0],
 'c_y': [6.0],
 'c_z': [7.0],
 'd_xx': [8.0],
 'd_xy': [9.0],
 'd_xz': [10.0],
 'd_yx': [11.0],
 'd_yy': [12.0],
 'd_yz': [13.0],
 'd_zx': [14.0],
 'd_zy': [15.0],
 'd_zz': [16.0]}
yade.plot.addAutoData()[source]

Add data by evaluating contents of plot.plots. Expressions rasing exceptions will be handled gracefully, but warning is printed for each.

>>> from yade import plot
>>> from pprint import pprint
>>> O.reset()
>>> plot.resetData()
>>> plot.plots={'O.iter':('O.time',None,'numParticles=len(O.bodies)')}
>>> plot.addAutoData()
>>> pprint(plot.data)
{'O.iter': [0], 'O.time': [0.0], 'numParticles': [0]}

Note that each item in plot.plots can be

  • an expression to be evaluated (using the eval builtin);
  • name=expression string, where name will appear as label in plots, and expression will be evaluated each time;
  • a dictionary-like object – current keys are labels of plots and current values are added to plot.data. The contents of the dictionary can change over time, in which case new lines will be created as necessary.

A simple simulation with plot can be written in the following way; note how the energy plot is specified.

>>> from yade import plot, utils
>>> plot.plots={'i=O.iter':(O.energy,None,'total energy=O.energy.total()')}
>>> # we create a simple simulation with one ball falling down
>>> plot.resetData()
>>> O.bodies.append(utils.sphere((0,0,0),1))
0
>>> O.dt=utils.PWaveTimeStep()
>>> O.engines=[
...    ForceResetter(),
...    GravityEngine(gravity=(0,0,-10),warnOnce=False),
...    NewtonIntegrator(damping=.4,kinSplit=True),
...    # get data required by plots at every step
...    PyRunner(command='yade.plot.addAutoData()',iterPeriod=1,initRun=True)
... ]
>>> O.trackEnergy=True
>>> O.run(2,True)
>>> pprint(plot.data)   
{'gravWork': [0.0, -25.13274...],
 'i': [0, 1],
 'kinRot': [0.0, 0.0],
 'kinTrans': [0.0, 7.5398...],
 'nonviscDamp': [0.0, 10.0530...],
 'total energy': [0.0, -7.5398...]}
yade.plot.saveGnuplot(baseName, term='wxt', extension=None, timestamp=False, comment=None, title=None, varData=False)[source]

Save data added with plot.addData into (compressed) file and create .gnuplot file that attempts to mimick plots specified with plot.plots.

Parameters:
  • baseName – used for creating baseName.gnuplot (command file for gnuplot), associated baseName.data.bz2 (data) and output files (if applicable) in the form baseName.[plot number].extension
  • term – specify the gnuplot terminal; defaults to x11, in which case gnuplot will draw persistent windows to screen and terminate; other useful terminals are png, cairopdf and so on
  • extension – extension for baseName defaults to terminal name; fine for png for example; if you use cairopdf, you should also say extension='pdf' however
  • timestamp (bool) – append numeric time to the basename
  • varData (bool) – whether file to plot will be declared as variable or be in-place in the plot expression
  • comment – a user comment (may be multiline) that will be embedded in the control file
Returns:

name of the gnuplot file created.

yade.plot.saveDataTxt(fileName, vars=None, headers=None)[source]

Save plot data into a (optionally compressed) text file. The first line contains a comment (starting with #) giving variable name for each of the columns. This format is suitable for being loaded for further processing (outside yade) with numpy.genfromtxt function, which recognizes those variable names (creating numpy array with named entries) and handles decompression transparently.

>>> from yade import plot
>>> from pprint import pprint
>>> plot.reset()
>>> plot.addData(a=1,b=11,c=21,d=31)  # add some data here
>>> plot.addData(a=2,b=12,c=22,d=32)
>>> pprint(plot.data)
{'a': [1, 2], 'b': [11, 12], 'c': [21, 22], 'd': [31, 32]}
>>> plot.saveDataTxt('/tmp/dataFile.txt.tar.gz',vars=('a','b','c'))
>>> import numpy
>>> d=numpy.genfromtxt('/tmp/dataFile.txt.tar.gz',dtype=None,names=True)
>>> d['a']
array([1, 2])
>>> d['b']
array([11, 12])
>>> import os # cleanup
>>> os.remove('/tmp/dataFile.txt.tar.gz')
Parameters:
  • fileName – file to save data to; if it ends with .bz2 / .gz, the file will be compressed using bzip2 / gzip.
  • vars – Sequence (tuple/list/set) of variable names to be saved. If None (default), all variables in plot.plot are saved.
  • headers – Set of parameters to write on header
yade.plot.savePlotSequence(fileBase, stride=1, imgRatio=(5, 7), title=None, titleFrames=20, lastFrames=30)[source]

Save sequence of plots, each plot corresponding to one line in history. It is especially meant to be used for utils.makeVideo.

Parameters:
  • stride – only consider every stride-th line of history (default creates one frame per each line)
  • title – Create title frame, where lines of title are separated with newlines (\n) and optional subtitle is separated from title by double newline.
  • titleFrames (int) – Create this number of frames with title (by repeating its filename), determines how long the title will stand in the movie.
  • lastFrames (int) – Repeat the last frame this number of times, so that the movie does not end abruptly.
Returns:

List of filenames with consecutive frames.