timeplot — visualizing temporal data ==================================== **timeplot** allows you to visualize temporal data in different ways, with the intention to help you spot patterns. It takes as input a sequence of events in a fixed format (there are several types of events), and draws the quantitative characteristics of that sequence in many different ways — e.g. you can **compare the frequency** of different types of events per time unit, or to look at the distribution of **event durations**, etc. **The input** to **timeplot** is a sequence of events of the form *event X happened*, *interval event X started/finished*, *a numeric or discrete variable P took value X*. Every event happens on a particular *input track* and at a particular time. The types of events are specified in section :ref:`tplot-input-format`. Different types of events can be used with different types of visualizations. **The output** is a vertical stack of plots with a common time axis. Each plot corresponds to one *output track*. Usually *input tracks* correspond to output tracks 1-to-1, but sometimes the relation is more complex (multiple tracks on 1 plot, or 1 track on multiple plots) — see :ref:`tplot-concepts`. Every output plot is one of several types (e.g. simple dot plot, line plot, quantile plot, etc.). The kind of plot to draw on a particular output track is specified by the *plot kind mapping*, also described in section :ref:`tplot-concepts`. An example result of **timeplot** is shown below: .. _tplot-motivating-example: .. figure:: pics/tplot/tplot-motivating-example.png :figwidth: 60% :align: center **timeplot** example: distribution of memcached access latencies from the same rack and from a different rack. Built from a log that had entries about starts and completions of requests to memcached. .. _tplot-simple-example: Simple example ---------------- This section considers in detail the simplest and most intuitive example possible: a dot plot of a single time-varying value. Assume that we have a program that sometimes does requests to a database server (*Arcadia* — this is a real-life example from Yandex, and Arcadia is the codename of its core search engine) and logs their durations:: ... 2010-05-11 18:25:05.435 Arcadia request took 820 ms ... We're interested in looking at the structure of these durations and its change over time. A simple dot plot is a perfect starting point. First, **generate the trace**: for each line of interest in the log, we need to emit a corresponding *numeric measurement* event into the trace (see reference on event types in section :ref:`tplot-concepts` and on their textual format in section :ref:`tplot-input-format`). The trace should look like this:: ... 2010-05-11 18:25:05.435 =arc 820 ... This is trivial to achieve with an awk one-liner:: $ awk '/Arcadia req/{print $1 " " $2 " =arc " $6}' log.txt > trace.txt Now we can **generate the plot**: we need to tell **timeplot** the input and output filenames and what kind of chart to draw:: $ tplot -if trace.txt -o arc.png -dk dots The parameter ``-dk`` means *default chart kind*: just draw all tracks (in this case the only track) using this kind of chart (``dots``). So, the track mapping process is involved here in the most trivial form (see section :ref:`tplot-track-mapping` for less trivial forms). And we get this: .. image:: pics/tplot/dots.png :width: 50% :align: center We see the following features: * The times clearly split into higher and lower values, obviously corresponding to cache hits and cache misses within Arcadia. * At some point the distribution suddenly changes to the worse and requests start taking more time. I do not remember what was the reason for that, but there certainly was one. * There's a lot of overplotting on the picture; it's difficult to understand the distribution more precisely. To do that, we'll need quantile plots or bin plots (see section :ref:`tplot-plot-kinds` ). An alternative is to use semi-transparent dots (e.g. ``-dk 'dots 0.3'`` would give 30% opacity). There exist other ways of coping with overplotting (just google *overplotting*), but they're not currently implemented in **timeplot**. **Where to go next:** From this simple example you can go several ways: * Get a glimpse of the power of **timeplot** in a more serious example — continue to section :ref:`tplot-motivation` where a reasonably complex real-world example is considered. * Explore the ways to **map event streams onto charts**: draw multiple tracks, display a single input data point on multiple charts or vice versa, display data points from multiple tracks on a single plot (e.g. a color-coded dot plot) — see section :ref:`tplot-track-mapping` . * Learn to use the **more complex event types** (e.g. discrete, impulse, edge and interval events) and to draw other types of charts on them — read section :ref:`tplot-concepts` and continue to section :ref:`tplot-plot-kinds` . * Draw more interesting **types of charts** — just go to section :ref:`tplot-plot-kinds` . * Take a look at the **example charts gallery** and choose something that looks interesting or applicable to your case — go to section :ref:`tplot-gallery` . .. _tplot-motivation: Motivation: More complex example --------------------------------- In this section we'll show a moderately complex real-world example of usage of **timeplot**, with the goal to show its power and inspire the reader to learn more, but without the goal to provide detailed explanations. To become capable of using **timeplot** for similar purposes *yourself*, you'll have to actually read the next chapters. Consider the log format described in the :ref:`introduction` — the one where tasks consist of a *fetching data from memcached* stage and *computational* stage, delimited by ``Begin``, ``GetCommonData``, ``End``. Suppose that we have several racks of servers and just one memcached server. Let us compare how memcached latencies differ when it is accessed by workers from different racks (since cross-rack access requires an extra network packet hop through a switch device, accesing from the same rack should be faster). memcached is on rack 1. Let us specifically compare performance on machines ``UNIT011`` and ``UNIT051``. So, we should expect access from ``UNIT011`` to be faster. The filtered log looks like this:: ... UNIT011 2010-12-09 01:54:41.853 P3964 Debug GetCommonData 390256d1/49 UNIT011 2010-12-09 01:54:41.927 P3964 Info Begin 390256d1/51 UNIT011 2010-12-09 01:54:41.928 P3964 Debug GetCommonData 390256d1/51 UNIT051 2010-12-09 01:54:42.045 P3832 Info Begin 390256d1/99 UNIT051 2010-12-09 01:54:42.045 P3164 Info Begin 390256d1/98 UNIT051 2010-12-09 01:54:42.046 P3164 Debug GetCommonData 390256d1/98 ... Let us make this into a trace file for **timeplot**:: $ awk '{t=$2 " " $3; p="memcached-" $1 "." $4} /Begin / {print t " >" p} /GetCommonData /{print t " <" p}' log.txt > trace.txt The trace will look like this:: ... 2010-12-09 01:54:41.853 memcached-UNIT011.P3964 2010-12-09 01:54:41.928 memcached-UNIT051.P3832 2010-12-09 01:54:42.045 >memcached-UNIT051.P3164 2010-12-09 01:54:42.046 `` means the beginning of an activity and ``<`` means the end (these are two of the different event types). Now we'll plot the distribution of durations of memcached access times according to these ``>`` and ``<`` events:: $ tplot -if trace.txt -o latencies.png -dk 'within[-] duration drop binf 10 0.001,0.002,0.005,0.01,0.05' For now do not concern yourself with the meaning of the value of the ``-dk`` parameter, it will be explained later (in section :ref:`tplot-plot-kinds` ). Just concentrate on the input (how easy it is to generate from the logs) and the output (how much it tells about the system). The result looks like this: .. image:: pics/tplot/tplot-motivating-example.png :width: 50% :align: center **Explanation of the output:** The graph above corresponds to access from ``UNIT011``, below from ``UNIT051``. Both graphs have time on the X axis and latency on the Y axis. Time is cut into 10-second bins represented by a stack of colored bars. Within each stack (see legend and compare to the invocation of ``tplot`` above): * Height of the green bar shows the fraction of latencies under 0.001s * Height of the blue bar shows the fraction of latencies in 0.001s--0.002s * Height of the yellow bar shows the fraction of latencies in 0.002s--0.005s * Height of the red bar shows the fraction of latencies in 0.005s--0.01s * Height of the orange bar shows the fraction of latencies in 0.01s--0.05s * Height of the brown bar shows the fraction of latencies above 0.05s Together these fractions add up to 1. **The graphs differ**: * There are **no green bars** on the second graph, i.e. access from a different rack is never under 0.001s * The **yellow bars are a lot larger** on the second graph, i.e. times in 0.002s--0.005s are much more frequent when accessing from a different rack **To reiterate:** given the log, the following commands:: $ awk '{t=$2 " " $3; p="memcached-" $1 "." $4} /Begin / {print t " >" p} /GetCommonData /{print t " <" p}' log.txt > trace.txt $ tplot -if trace.txt -o latencies.png -dk 'within[-] duration drop binf 10 0.001,0.002,0.005,0.01,0.05' ... give us the figure above which shows how exactly the distributions of access latencies from different racks differ and emphasize the importance of choosing a nearby memcached according to network topology. This example illustrated the mode of usage of **timeplot**, the ease of generating input for it from an arbitrary log and the terseness of its syntax for specifying the kind of graph to be plotted. We'll now give some basic definitions and then proceed to a formal and exhaustive reference. .. _tplot-concepts: Concepts -------- This section lists the concepts necessary for precisely understanding the rest of the manual. You can quickly skim over them now just to get a feeling of what they're about, and return to them later when something is unclear. * **Event** The unit of information in the input trace. It can be one of several types: *something has happened* (an *impulse event*), *something has started/finished* (an *edge event*, and the activity delimited by start/finish is called an *interval event*), *some magnitude had a particular value* (*measurement event*) etc. This corresponds to typical log entries, so events are easy to generate from logs. Each event happens on a particular *input track* and at a particular time, for example: ``2012-06-04 14:24:05.384 =rtime.mcd1 5.371`` is a numeric measurement event (``=``) that happened on track ``rtime.mcd1`` at ``2012-06-04 14:24:05.384`` . * **Input track** A named group of events in the *input trace*. Usually corresponds to a single magnitude being measured or to a single family of activities, e.g. there could be an input track for request execution times named ``rtime`` or a track for types of received messages by client C1 named ``mtype-C1``. Thus, an input track nearly always consists of events of the same type (see different types of events described in section :ref:`tplot-input-format` ). * **Output track** A named group of events in the *output plots*. The grouping of output tracks is often, but not necessarily, identical to the grouping of input tracks (see section :ref:`tplot-track-mapping` ). All events with the same output track are shown on the same output plot. * **Output plot** A single plot in the resulting picture. The picture consists of several output plots vertically stacked together with a common time axis. A single output plot is based on values from a single output track, which may have events from one or more input tracks. * **Plot kind** The type of an output plot: e.g. dot plot, line plot, quantile plot etc. Plot kinds usually have parameters, e.g. the percentiles of interest on a quantile plot. Plot kinds are described in section :ref:`tplot-plot-kinds` . * **Plot kind mapping** The process by which we determine what plot kind to use for a particular output track. Happens together with *track mapping* . * **Track mapping** The process by which events from different input tracks are mapped onto output tracks, e.g. to show several magnitudes on a single plot or vice versa (show a single magnitude in several different ways). See section :ref:`tplot-track-mapping` . To put it together: Input events belong to input tracks and get mapped onto output tracks via track mapping. Every output track gives rise to an output plot, its kind determined by plot kind mapping. Output plots are stacked vertically with a common time axis. The following concepts are important for understanding the different event types and some plots produced from them: * **Measurement event** An event that denotes that a particular magnitude was measured to have a particular value (e.g.: the amount of free memory was measured to be 2.5Gb), or that something happened with a particular value of a parameter. E.g.: an I/O write request *for 65536 bytes* arrived (e.g. ``... =writeBytes 65536``) — a numeric measurement; or an I/O request *of type "write"* has arrived (e.g. ``... =requestType `WRITE``) — a discrete measurement. * **Impulse event** An input event without parameters that just denotes that something has happened, determined solely by its input track. E.g. if you're interested in the number of completed requests per second (e.g. ``... !requestCompleted``), you can have an input trace with impulse events on the track ``requestCompleted`` and draw an *activity count* plot of that (``acount``). * **Edge event (counter bump)** An input event without parameters that denotes that some activity (interval event) has *started* or *finished*. It can at the same time be thought of as a bump of +1 (``>request``) or -1 (``request``, ``=@]TRACK [VALUE] For example:: 2012-06-04 14:24:13.389 !requestCompleted 2012-06-04 14:24:13.389 !userLogIn Joe 2012-06-04 14:24:13.389 >request.mcd1 2012-06-04 14:24:13.389 TRACK`` | Interval event start / counter bump +1 | ``>requests`` | +-------------------+-----------------------------------------+-----------------------+ | ```` */* ``<`` *) on this track''* (see section :ref:`tplot-concepts` ). Durations are measured in seconds. If ``drop`` is specified, then names of the original input tracks are replaced by the name of the output track (of course, this only makes a difference if multiple input tracks map to this output track, i.e. if we're speaking about ``within[SEP] duration drop``). For example, suppose you're measuring **processing of requests by several stages** of a single-threaded pipeline (i.e., every stage of the pipeline processes at most 1 item at a time). Then your log might say:: .... >process.stage1 .... >process.stage2 .... process.stage3 .... >process.stage1 .... process.14ca3ef7 .... v_M`. Frequencies are numbers from 0 to 1, so they add up to 1, so the total height of the bars is always 1. **Bin histogram plot** — ``binh N`` :math:`v_1,v_2,..,v_M` — same as ``binf``, but instead of frequencies, the absolute number of occurences of each bin is drawn. For both of these, only 1 input track per output track is supported. Example of both ``binh`` (top) and ``binf`` (bottom): .. image:: pics/tplot/binf-binh.png :width: 50% :align: center *(this graph was made with an old version of* **timeplot** *which had a pretty ugly color scheme)* Here the same value (page download time by a web crawler) is drawn using both ``binf`` and ``binh``: we see how frequently the download took below 100ms, 100 to 500ms, 500 to 1000ms etc. On the top graph we see *what number* of pages took that much to download, and on the bottom graph we see *what fraction* of pages took that much. In different situations both of these can be useful. Plot kinds for counters ^^^^^^^^^^^^^^^^^^^^^^^ **Event plot** — ``event`` — draw intervals delimited by ``>`` and ``<`` input events and markers according to ``@`` and ``!`` events. In the more complex case where ``>`` and ``<`` do not strictly alternate, they are interpreted as *+1* and *-1*-s to a counter and **timeplot** draws intervals when the counter is greater than zero. Only 1 input track per output track supported. If you need to draw something similar to what ``event`` does, but more complex, you might consider using **splot** instead. ``@TRACK COLOR`` events act as ``>`` but the bar will have the indicated color. ``!TRACK`` will draw a vertical red dash and ``!TRACK TEXT`` will draw a red dash with a text label. Example (``-dk event``): a computation had to process 10 *sites*, processing at most 6 concurrently. Starting computations for a site was marked with ``>site-N`` and completion with ````, ``<`` and ``!`` in each bin. More specifically: * Each input track mapping to this output track is interpreted as a counter * ``>`` means *+1*, ``<`` means *-1*, ``!`` are counted separately * In every bin, draw stacked bars: 1 bar per input track mapped to this output track (with a consistent coloring across bins), height of the bar is average value of the counter + number of ``!`` events in this bin (usually you *either* use ``>`` and ``<``, *or* ``!``), divided by bin width (so the graph gives *rate per second* and is scale-invariant under change of N). Example with 1 input track per output track: ``acount 5`` .. image:: pics/tplot/acount-begin-end-running.png :width: 50% :align: center Here, we draw how many tasks are being 1) started 2) finished 3) currently running, for every 5 seconds. The trace looked like this:: ... 2010-12-02 07:08:15 !begin/5s 2010-12-02 07:08:15 >running ... 2010-12-02 07:08:18 !end/5s 2010-12-02 07:08:18 `` and ``<``. Example with two input tracks per output track: ``within[.] acount 5`` .. image:: pics/tplot/tplot-preemption.png :width: 50% :align: center Here we see how the cluster is executing one job at full capacity, then another job comes in, preempts some of the first job's tasks and starts its own tasks there, etc. Each job's task starts are mapped to ``>job.JOBID`` and task completions are mapped to ``run.S`` is emitted; when it finishes, ```` and ``<`` at any given moment. Example with both 1 and several input tracks per output track: ``+k run 'apercent 60 420' +k run 'within[.] apercent 60 420'`` .. image:: pics/tplot/tplot-three-jobs.png :width: 50% :align: center *The original log has been lost and only a picture with manually erased axis labels was left. Originally, there were labels on all axes. 1 tick on the X axis is actually 1 hour.* Here, three jobs are being executed on a cluster with 420 cores. The graphs show utilization of the cluster (what percentage of cores are busy at any given moment) by the 3 jobs separately and as a whole. When a task starts, an event ``>run.JOBID`` is emitted; when a task completes, ```_ but with fractional seconds supported via ``%OS`` — will parse ``12.4039`` or ``12,4039``. Also, ``%\^[+-][N]s`` will parse seconds since the epoch, for example ``%\^-3s`` are milliseconds since the epoch (N can only be 1 digit) - ``%Y-%m-%d %H:%M:%OS`` * - ``-dk KIND`` - Default diagram kind. Do not forget to quote it! See section :ref:`tplot-track-mapping` . - None * - ``+dk KIND`` - --- - None * - ``-k PATTERN KIND`` - Diagram kind for pattern PATTERN. See section :ref:`tplot-track-mapping` . - None * - ``+k PATTERN KIND`` - --- - None * - ``-fromTime TIME`` - Filter events whose time is :math:`\ge` this time. Format specified by ``-tf``. - None (no filter) * - ``-toTime TIME`` - Filter events whose time is :math:`\le` this time. Format specified by ``-tf``. - None (no filter) * - ``-baseTime TIME`` - Draw time axis labels as seconds elapsed since TIME, instead of absolute time. Format specified by ``-tf``. - None Example data and exercises --------------------------- In this section we list some example datasources and exercises to try on them. **WARNING:** The section :ref:`tplot-gallery` has solutions to many of the exercises. Don't look at graphs marked *exercise* if you don't want a spoiler. Consumer power consumption. ^^^^^^^^^^^^^^^^^^^^^^^^^^^ http://archive.ics.uci.edu/ml/datasets/Individual+household+electric+power+consumption. This dataset contains measurements of power consumption of a single household, measuring several characteristics over the course of several years. It's in a simple CSV format which is described at the link. Beware: some data is not available and there are question marks in place of missing data items. You can completely skip such rows for the purpose of this exercise. **Excerpt from the log**:: Date;Time;Global_active_power;Global_reactive_power;Voltage;Global_intensity;Sub_metering_1;Sub_metering_2;Sub_metering_3 16/12/2006;17:24:00;4.216;0.418;234.840;18.400;0.000;1.000;17.000 16/12/2006;17:25:00;5.360;0.436;233.630;23.000;0.000;1.000;16.000 16/12/2006;17:26:00;5.374;0.498;233.290;23.000;0.000;2.000;17.000 16/12/2006;17:27:00;5.388;0.502;233.740;23.000;0.000;1.000;17.000 16/12/2006;17:28:00;3.666;0.528;235.680;15.800;0.000;1.000;17.000 **Exercise 1.** Make a dot plot of ``Voltage`` for January 1st, 2007. Do not limit *the trace*, use ``-fromTime`` and ``-toTime``. :download:`Expected result ` **Exercise 2.** Make a line plot of ``Global_active_power`` vs ``Global_reactive_power`` on one plot and a line plot of ``Voltage`` on another (i.e., the result should be a stack of two plots), for January 1st, 2007. Use an opacity level of 0.5. :download:`Expected result ` **Exercise 3.** Make a quantile plot, with quantiles of 0.1, 0.5 and 0.9 over bins of 1 day, for ``Global_active_power`` and ``Voltage``, for the entire dataset. :download:`Expected result ` Video encoding ^^^^^^^^^^^^^^^ *This dataset generously provided by Dmitry Popov.* http://jkff.info/datasets/dmitry-popov-video-encoding.tar.gz. This is a set of logs of a video encoding pipeline. For every video sample, the log contains times that this sample entered several steps of the pipeline: ``Grab1``, ``Grab2``, ``SR.YUV`` and ``AviWr``. The three logs show how the same video was encoded with 3 versions of the program after different optimizations. **Excerpt from the log:** This excerpt shows all entries in the log ``1.txt`` relating to sample ``[0]``. In the full log, entries for all samples are intermixed. Use column 1 as the timestamp:: 0.000000 (0.000000) (0.000000) Grab1 sample [0] 0.000000, locking.. 0.000006 (0.000006) (0.000006) Grab1 [0] got lock, carry on.. 0.000611 (0.000604) (0.000611) Grab1 [0] sample processed. 0.000615 (0.000000) (0.000615) Par1.In received sample [0] 0.000629 (0.000000) (0.000629) SR.YUV got sample [0] 0.011636 (0.011007) (0.011636) SR.YUV done with sample [0] 0.011643 (0.000000) (0.011643) ParLast.In received sample [0] 0.011661 (0.000000) (0.011661) Grab2 sample [0] 0.000000, locking.. 0.011666 (0.000005) (0.011666) Grab2 [0] got lock, carry on.. 0.014947 (0.003280) (0.014947) Grab2 [0] sample processed. 0.598770 (0.000000) (0.598770) AviWr.V video sample [0] received 9.736371 (0.000466) (9.736371) AviWr.V [0] WriteVideo, locking.. 9.736373 (0.000001) (9.736373) AviWr.V [0] got lock, writing.. 9.736460 (0.000086) (9.736460) AviWr.V [0] write complete. **Exercise 1.** Plot the number of samples arriving per second to ``Grab1``, ``Grab2``, ``SR.YUV`` and ``AviWr``. :download:`Expected result ` **Exercise 2.** Make an event plot, using impulse events for sample arrivals to these stages. Limit to the first 20 seconds. :download:`Expected result ` **Exercise 3.** Make 4 dot plots for durations of processing at these stages. :download:`Expected result ` **Exercise 4.** Plot the same, but on a single plot (hint: use ``within``). :download:`Expected result ` DrWeb log ^^^^^^^^^^ *This log was generously provided by Paul Graphov.* http://jkff.info/datasets/paul-graphov-drweb.tar.gz. This is a log of DrWeb Antivirus Server, and the most interesting entries in it are those relating to TCP data flow and to DB transactions:: 20121024.114904.78 db3 [ 415 448] mth:1 ...:ANTON-WIN7RU: data arrived, 32b 20121024.114904.78 tr2 [ 415 448] mth:1 ...:ANTON-WIN7RU: rcv 17 GETTIME(6348666174470429760) 0b data 20121024.114904.78 db3 [ 415 448] mth:1 ...:ANTON-WIN7RU: cancel timeout, GETTIME 20121024.114904.78 tr2 [ 415 448] mth:1 ...:ANTON-WIN7RU: cmd (49b) "11 TIME 6348666174470429760 6348666174478278600" 20121024.114904.78 db3 [ 415 448] mth:1 ...:ANTON-WIN7RU: cancel timeout, prolongate 20121024.114904.78 db3 [ 415 448] mth:1 ...:ANTON-WIN7RU: set timeout to 60000 ms <6348666180478295800> 20121024.114904.78 db3 [ 415 449] mth:2 ...:ANTON-WIN7RU: data arrived, 14b and:: 20121024.114904.78 db3 [ 415 449] mth:2 [DB] Successful BEGIN transaction, 00.000 wait 20121024.114904.78 db3 [ 415 449] mth:2 [IntDB] Statement "..." 20121024.114904.78 db3 [ 415 449] mth:2 [DB] OK, 00.000, ... 20121024.114904.78 db3 [ 415 449] mth:2 [IntDB] Statement "..." 20121024.114904.78 db2 [ 415 449] mth:2 [DB] 1 row, 00.000, ... 20121024.114904.78 db3 [ 415 449] mth:2 [IntDB] Statement "..." 20121024.114904.78 db2 [ 415 449] mth:2 [DB] 79 rows, 00.000, ... 20121024.114904.78 db3 [ 415 449] mth:2 [IntDB] Statement "COMMIT" 20121024.114904.78 db3 [ 415 449] mth:2 [DB] Database has been freed but nobody wants it now 20121024.114904.78 db3 [ 415 449] mth:2 [DB] Successful COMMIT transaction, 3 statements, 00.000 wait, 00.000 execute, 00.000 commit **Exercise 1.** Plot the data arrival rate (according to ``data arrived`` entries) per 5-second bins (use ``sum``). :download:`Expected result ` **Exercise 2.** Plot the transaction commit rate (according to ``Successful COMMIT`` entries) per 5-second bins. :download:`Expected result ` **Exercise 3.** Plot the same transaction commit rate, but so that we can see how it adds up from contributions by different threads (``mth:1``, ``pth:2`` etc.). Limit to the interval from 12:00 to 13:00. :download:`Expected result ` **Exercise 4.** Same as above, *and use the same trace file*, but make it 1 plot per thread type (``mth``, ``pth``, ``dbv`` etc., but still with a breakdown *by thread* within each type's plot). :download:`Expected result ` .. _tplot-gallery: Gallery --------- Look for plots that seem like what you want. Consult sections :ref:`tplot-input-format` , :ref:`tplot-plot-kinds` and :ref:`tplot-track-mapping` . Simplest numeric plots and basic track mapping ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. figure:: pics/tplot/dots.png :width: 50% :align: center A dot plot of request execution times. 1 input track, 1 output track. Events look like ``=arc 1542``, plot type ``-dk dots``. Data provided by Julia Astakhova .. figure:: pics/tplot/dots-create-user-and-profile.png :width: 50% :align: center A dot plot of two parts of request execution times. 2 input tracks, 1 output track. Events look like ``=t.createUser 25`` or ``=t.createProfile 7``, plot type ``-dk 'within[.] dots'``. Data provided by Julia Astakhova. .. figure:: pics/tplot/dots-create-user-and-profile-alpha.png :width: 50% :align: center Same as above but with transparency. Plot type ``-dk 'within[.] dots 0.2'`` .. figure:: pics/tplot/binf-binh.png :width: 50% :align: center Distribution of page download times by a web crawler — how many take :math:`<100` ms, :math:`100..500` etc. this is actually 2 different picture stitched together. each had 1 input track with events like ``=time 254.1``. Drawn with ``-dk 'binh 900'`` and ``-dk 'binf 900'`` correspondingly (15-minute slices). .. figure:: pics/tplot/dist-quantile.png :width: 50% :align: center Distribution of request execution times and rate of request completions per minute in an akka program. events look like ``>akka.THREADID``, ``site-5``, ``running``, ``running`` and ``fly.JOBID``, ``run.JOBID`` and ``