Adding plots to the simulation
Some modelers like to monitor simulation progress bydisplaying “live” plots that characterize current state of the simulation. In CC3D it is very easy to add to the Player windows. The best way to add plots is via Twedit++ CC3D Python->Scientific Plots menu. Take a look at example code to get a flavor of what is involved when you want to work with plots in CC3D:
class cellsortingSteppable(SteppableBasePy): def __init__(self, _simulator, _frequency=1): SteppableBasePy.__init__(self, _simulator, _frequency) def start(self): self.pW = self.addNewPlotWindow( _title='Average Volume And Volume of Cell 1', _xAxisTitle='MonteCarlo Step (MCS)', _yAxisTitle='Variables', _xScaleType='linear', _yScaleType='log', _grid=True # only in 3.7.6 or higher ) self.pW.addPlot('AverageVol', _style='Dots', _color='red', _size=5) self.pW.addPlot('Cell1Vol', _style='Steps', _color='black', _size=5) def step(self, mcs): averVol = 0.0 numberOfCells = 0 for cell in self.cellList: averVol += cell.volume numberOfCells += 1 averVol /= float(numberOfCells) cell1 = self.attemptFetchingCellById(1) print cell1 self.pW.addDataPoint("AverageVol", mcs, averVol) # name of the data series, x, y self.pW.addDataPoint("Cell1Vol", mcs, cell1.volume) # name of the data series, x, y # self.pW.showAllPlots() # no longer necessary
start function we create plot window (
self.pW) – the arguments of
this function are self explanatory. After we have plot windows object
self.pW) we are adding actual plots to it. Here we will plot two
time-series data, one showing average volume of all cells and one
showing instantaneous volume of cell with id 1:
We are specifying here plot symbol types (
Steps), their sizes and
colors. The first argument is then name of the data series. This name
has two purposes – 1. It is used in the legend to identify data points
and 2. It is used as an identifier when appending new data. We can also
specify logarithmic axis by using
_yScaleType='log' as in the example
step function we are calculating average volume of all cells and
extract instantaneous volume of cell with id
1. After we are done with
calculations we are adding our results to the time series:
self.pW.addDataPoint("AverageVol",mcs,averVol) # name of the data series, x, y self.pW.addDataPoint("Cell1Vol",mcs,cell1.volume) # name of the data series, x, y
Notice that we are using data series identifiers (
Cell1Vol) to add new data. The second argument in the above function
calls is current Monte Carlo Step (mcs) whereas the third is actual
quantity that we want to plot on Y axis. We are done at this point
Important: Previous versions of CC3D required users to explicitly update plots by calling self.pW.showAllPlots() . *This is no longer necessary although including this call will not cause any side-effects *. self.pW.showAllPlots() # DEPRECATED
The results of the above code may look something like:
Figure 13 Displaying plot window in the CC3D Player with 2 time-series data.
Notice that the code is fairly simple and, for the most parts, self-explanatory. However, the plots are not particularly pretty and they all have same style. This is because this simple code creates plots based on same template. The plots are usable but if you need high quality plots you should save your data in the text data-file and use stand-alone plotting programs. Plots provided in CC3D are used mainly as a convenience feature and used to monitor current state of the simulation.
Adding histograms to CC3D player is a bit more complex than adding
simple plots. This is because you need to first process data to produce
histogram data. Fortunately Numpy has the tools to make this task
relatively simple. An example
CompuCellPythonTutorial demonstrates the use of histogram. Let us look
at the example steppable (you can also find relevant code snippets in
CC3D Python-> Scientific Plots menu):
class HistPlotSteppable(SteppableBasePy): def __init__(self, _simulator, _frequency=10): SteppableBasePy.__init__(self, _simulator, _frequency) def start(self): # initialize setting for Histogram self.pW = self.addNewPlotWindow(_title='HIstogram', _xAxisTitle='Cell #', _yAxisTitle='Volume') # _alpha is transparency 0 is transparent, 255 is opaque self.pW.addHistogramPlot(_plotName='Hist 1', _color='green', _alpha=100) self.pW.addHistogramPlot(_plotName='Hist 2', _color='red') self.pW.addHistogramPlot(_plotName='Hist 3', _color='blue') def step(self, mcs): volList =  for cell in self.cellList: volList.append(cell.volume) gauss =  for i in range(100): gauss.append(random.gauss(0, 1)) self.pW.addHistogram(plot_name='Hist 1', value_array=gauss, number_of_bins=10) self.pW.addHistogram(plot_name='Hist 2', value_array=volList, number_of_bins=10) self.pW.addHistogram(plot_name='Hist 3', value_array=volList, number_of_bins=50) fileName = "HistPlots_" + str(mcs) + ".png" self.pW.savePlotAsPNG(fileName, 1000, 1000) # here we specify size of the image fileName = "HistPlots_" + str(mcs) + ".txt" self.pW.savePlotAsData(fileName)
In the start function we call
self.addNewPlotWindow to add new plot
self.pW- to the Player. Subsequently we specify display
properties of different data series (histograms). Notice that we can
specify opacity using
In the step function we first iterate over each cell and append their volumes to Python list. Later plot histogram of the array using a very simple call:
self.pW.addHistogram(plot_name='Hist 2' , value_array=volList ,number_of_bins=10)
that takes an array of values and the number of bins and adds histogram to the plot window.
Alternatively we may use slightly more complex way od adding histogram which in some situations may actually give you a bit more control. First we bin array of values using numpy functionality:
(n, bins) = numpy.histogram(volList, bins=10)
The return values are two numpy arrays: n which specifies center of the bin (we plot it on x axis) and bins which determines stores counts for a given bin.
Important: Make sure you import random and numpy modules in the steppable file. Place the following code:
import random, numpy
at the top of the file.
Next you add histogram data output from numpy to the plot using the following call:
self.pW.addHistPlotData('Hist 2', n, bins)
The following snippet:
gauss =  for i in range(100): gauss.append(random.gauss(0,1)) (n2, bins2) = numpy.histogram(gauss, bins=10)
declares gauss as Python list and appends to it 100 random numbers which are taken from Gaussian distribution centered at 0.0 and having standard deviation equal to 1.0. We histogram those values using the following code:
self.pW.addHistogram(plot_name='Hist 1' , value_array = gauss ,number_of_bins=10)
When we look at the code in the
start function we will see that this
data series will be displayed using green bars.
showAllHistPlots is no longer necessary
At the end of the steppable we output histogram plot as a png image file using:
two last arguments of this function represent x and y sizes of the image.
Imnportant: as of writing this manual we do not support scaling of the plot image output. This might change in the future releases, however we strongly recommend that you save all the data you plot in a separate file and post-process it in the full-featured plotting program
We construct fileName in such a way that it contains MCS in it.
The image file will be written in the simulation outpt directory.
Finally, for any plot we can output plotted data in the form of a text
file. All we need to do is to call
savePlotAsData from the plot windows
This file will be written in the simulation output directory. You can use it later to post process plot data using external plotting software.