XY Series

An XY series plot is generally used to show values over a continuum, such as time. XY Series plots can be represented as a line, a bar, an area or as a collection of points. The X axis is used to show the domain, while the Y axis shows the related values at specific points in the range.

Data Sourcing

XY Series plots can be created using data from tables, arrays and functions.

Creating an XY Series Plot using Data from a Table

When data is sourced from a table, the following syntax can be used to create an XY Series plot:

.plot("SeriesName", source, "xCol", "yCol").show()

  • plot is the method used to create an XY series plot.
  • "SeriesName" is the name (as a string) you want to use to identify the series on the plot itself.
  • source is the table that holds the data you want to plot.
  • "xCol" is the name of the column of data to be used for the X value.
  • "yCol" is the name of the column of data to be used for the Y value.
  • show tells Deephaven to draw the plot in the console.

The example query below will create an XY series plot that shows the price of a single security (AAPL) over time.

Note

Python users must import the appropriate module: from deephaven import Plot or from deephaven import Plot as plt

//source the data
t1 = db.t("LearnDeephaven","StockTrades").where("Date=`2017-08-24`")

//plot the data
PlotSingle = plot("AAPL", t1.where("USym = `AAPL`"), "Timestamp", "Last")
        .xBusinessTime()
        .show()
from deephaven import Plot

# source the data
t1 = db.t("LearnDeephaven", "StockTrades").where("Date=`2017-08-24`")

# plot the data
PlotSingle = Plot.plot("AAPL", t1.where("USym = `AAPL`"), "Timestamp", "Last")\
    .xBusinessTime()\
    .show()

Tip

The xBusinessTime method limits the data to actual business hours.

img

Creating an XY Series Plot using Data from an Array

When data is sourced from an array, the following syntax can be used to create an XY Series plot:

.plot("SeriesName", [x], [y]).show()

  • plot is the method used to create an XY series plot.
  • "SeriesName" is the name (as a string) you want to use to identify the series on the plot itself.
  • [x] is the array containing the data to be used for the X value.
  • [y] is the array containing the data to be used for the Y value.
  • show tells Deephaven to draw the plot in the console.

Creating an XY Series Plot using Data from a Function

When data is sourced from a function, the following syntax can be used to create an XY Series plot:

.plot("SeriesName", function).show()

  • plot is the method used to create an XY series plot.
  • "SeriesName" is the name (as a string) you want to use to identify the series on the plot itself.
  • function is a mathematical operation that maps one value to another. Examples of Groovy functions and their formatting follow:
    • {x->x+100} adds 100 to the value of x.
    • {x->x*x} squares the value of x.
    • {x->1/x} uses the inverse of x.
    • {x->x*9/5+32} Fahrenheit to Celsius conversion.
  • show tells Deephaven to draw the plot in the console.

Special Considerations When Plotting from a Function

If you are plotting a function in a plot by itself, consider applying a range for the function using the funcRange or xRange method. Otherwise, the default value ([0,1]) will be used, which may not meet your requirements:

.plot("Function", {x->x*x} ).funcRange(0,10).show()

If the function is being plotted with other data series, the funcRange method is not needed, and the range will be obtained from the other data series.

When using a function plot, you may also want to increase or decrease the granularity of the plot by declaring the number of points to include in the range. This is configurable using the funcNPoints method:

.plot("Function", {x->x*x} ).funcRange(0,10).funcNPoints(55).show()

XY Series with Shared Axes

You can compare multiple series over the same period of time by creating an XY series plot with shared axes. In the following example, two series are plotted, thereby creating two line graphs on the same plot.

//source the data
t2 = db.t("LearnDeephaven","StockTrades")
        .where("Date=`2017-08-24`","USym in `INTC`,`CSCO`")

//plot the data
plotSharedAxis = plot("INTC", t2.where("USym = `INTC`"), "Timestamp", "Last")
        .plot("CSCO", t2.where("USym = `CSCO`"), "Timestamp", "Last")
        .xBusinessTime()
        .show()
from deephaven import Plot

# source the data
t2 = db.t("LearnDeephaven", "StockTrades")\
    .where("Date=`2017-08-24`", "USym in `INTC`,`CSCO`")

# plot the data
plotSharedAxis = Plot.plot("INTC", t2.where("USym = `INTC`"), "Timestamp", "Last")\
    .plot("CSCO", t2.where("USym = `CSCO`"), "Timestamp", "Last")\
    .xBusinessTime()\
    .show()

img

Subsequent series can be added to the plot by adding additional plot() methods to the query. However, the plotBy() method can also be used to do this.

Note

See plotBy(./)

XY Series with Multiple X or Y Axes

When plotting multiple series in a single plot, the range of the Y axis is an important factor to watch. In the previous example, both securities had values within in a relatively narrow range (31 to 35). Therefore, any change in values was easy to visualize. However, as the range of the Y axis increases, those changes become harder to assess.

To demonstrate this, let's plot AAPL and GOOG on the same chart:

//source the data
t3 = db.t("LearnDeephaven","StockTrades").where("Date=`2017-08-24`","USym in `AAPL`,`GOOG`")

//plot the data
plotShared2 = plot("AAPL", t3.where("USym = `AAPL`"), "Timestamp", "Last")
        .plot("GOOG", t3.where("USym = `GOOG`"), "Timestamp", "Last")
        .xBusinessTime()
        .show()
from deephaven import Plot

# source the data
t3 = db.t("LearnDeephaven", "StockTrades").where("Date=`2017-08-24`", "USym in `AAPL`,`GOOG`")

# plot the data
plotShared2 = Plot.plot("AAPL", t3.where("USym = `AAPL`"), "Timestamp", "Last")\
    .plot("GOOG", t3.where("USym = `GOOG`"), "Timestamp", "Last")\
    .xBusinessTime()\
    .show()

Now, the scale of the Y axis needs to cover a much wider range (from 150 to 950), which results in relatively flat lines with barely distinguishable differences in values or trend.

img

This issue can be easily remedied by adding a second Y axis to the plot via the twinX() method.

twinX

The twinX() method enables you to use one Y axis for some of the series being plotted and a second Y axis for the others, while sharing the same X axis:

PlotName = figure().plot(...).twinX().plot(...).show()

  • The plot(s) for the series placed before the twinX() method share a common Y axis (on the left).
  • The plot(s) for the series listed after the twinX() method share a common Y axis (on the right).
  • All plots share the same X axis.

For example, we can create an improved chart for AAPL and GOOG together:

//source the data
t4 = db.t("LearnDeephaven","StockTrades").where("Date=`2017-08-24`","USym in `AAPL`,`GOOG`")

//plot the data
plotSharedTwinX = plot("AAPL", t4.where("USym = `AAPL`"), "Timestamp", "Last")
    .twinX()
    .plot("GOOG", t4.where("USym = `GOOG`"), "Timestamp", "Last")
    .xBusinessTime()
    .show()
from deephaven import Plot

# source the data
t4 = db.t("LearnDeephaven", "StockTrades").where("Date=`2017-08-24`", "USym in `AAPL`,`GOOG`")

# plot the data
plotSharedTwinX = Plot.plot("AAPL", t4.where("USym = `AAPL`"), "Timestamp", "Last")\
    .twinX()\
    .plot("GOOG", t4.where("USym = `GOOG`"), "Timestamp", "Last")\
    .xBusinessTime()\
    .show()

The value range for AAPL is shown on the left axis and the value range for GOOG is shown on the right axis:

img

twinY

The twinY() method enables you to use one X axis for one set of the values being plotted and a second X axis for another, while sharing the same Y axis:

PlotName = figure().plot(...).twinY().plot(...).show()

  • The plot(s) for the series placed before the twinY() method use the lower X axis.
  • The plot(s) for the series listed after the twinY() method use the upper X axis.

Plot Styles

The XY series plot in Deephaven defaults to a line plot. However, Deephaven's plotStyle() method can be used to format XY series plots as area charts, stacked area charts, bar charts, stacked bar charts, scatter charts and step charts.

In any of the examples below, you can simply swap out the .plotStyle() argument with the appropriate name; e.g., ("area"), ("stacked_area"), ("step"), etc.

Note

See Plot Styles

XY Series as a Stacked Area Plot

t5 = db.t("LearnDeephaven", "EODTrades")
    .where("ImportDate = `2017-11-01`", "Ticker in `AAPL`, `MSFT`")
    .update("DateString = EODTimestamp.toDateString(TZ_NY)")
    .where("inRange(DateString, `2016-11-01`, `2016-12-01`)")

plotXYStackedArea = plot("AAPL", t5.where("Ticker = `AAPL`"), "EODTimestamp", "Volume")
    .plot("MSFT", t5.where("Ticker = `MSFT`"), "EODTimestamp", "Volume")
    .chartTitle("Trades Per Day By Ticker")
    .xLabel("Date")
    .yLabel("Volume")
    .plotStyle("stacked_area")
    .show()
from deephaven import Plot

t5 = db.t("LearnDeephaven", "EODTrades")\
    .where("ImportDate = `2017-11-01`", "Ticker in `AAPL`, `MSFT`")\
    .update("DateString = EODTimestamp.toDateString(TZ_NY)")\
    .where("inRange(DateString, `2016-11-01`, `2016-12-01`)")

plotXYStackedArea = Plot.plot("AAPL", t5.where("Ticker = `AAPL`"), "EODTimestamp", "Volume")\
    .plot("MSFT", t5.where("Ticker = `MSFT`"), "EODTimestamp", "Volume")\
    .chartTitle("Trades Per Day By Ticker")\
    .xLabel("Date")\
    .yLabel("Volume")\
    .plotStyle("stacked_area")\
    .show()

img

XY Series as a Scatter Plot


t6 = db.t("LearnDeephaven", "StockTrades")
    .where("Date = `2017-08-25`", "USym in `AAPL`, `GOOG`, `MSFT`")
    .update("TimeBin = lowerBin(Timestamp, SECOND)")
    .firstBy("TimeBin")
    .where("TimeBin > '2017-08-25T10:00 NY' && TimeBin < '2017-08-25T11:00 NY'")

plotXYScatter = plot("AAPL", t6.where("USym = `AAPL`"), "Timestamp", "Last")
    .plotStyle("scatter")
    .pointSize(0.5)
    .pointColor(colorRGB(0,0,255,50))
    .pointShape("circle")
    .twinX()
    .plot("MSFT", t6.where("USym = `MSFT`"), "Timestamp", "Last")
    .plotStyle("scatter")
    .pointSize(0.8)
    .pointColor(colorRGB(255,0,0,100))
    .pointShape("up_triangle")
    .chartTitle("AAPL vs MSFT (10-11am ET)")
    .show()

from deephaven import Plot

t6 = db.t("LearnDeephaven", "StockTrades")\
    .where("Date = `2017-08-25`", "USym in `AAPL`, `GOOG`, `MSFT`")\
    .update("TimeBin = lowerBin(Timestamp, SECOND)")\
    .firstBy("TimeBin")\
    .where("TimeBin > '2017-08-25T10:00 NY' && TimeBin < '2017-08-25T11:00 NY'")

plotXYScatter = Plot.plot("AAPL", t6.where("USym = `AAPL`"), "Timestamp", "Last")\
    .plotStyle("scatter")\
    .pointSize(0.5)\
    .pointColor(Plot.colorRGB(0,0,255,50))\
    .pointShape("circle")\
    .twinX()\
    .plot("MSFT", t6.where("USym = `MSFT`"), "Timestamp", "Last")\
    .plotStyle("scatter")\
    .pointSize(0.8)\
    .pointColor(Plot.colorRGB(255,0,0,100))\
    .pointShape("up_triangle")\
    .chartTitle("AAPL vs MSFT (10-11am ET)")\
    .show()

img

XY Series as a Step Plot

t7 = db.t("LearnDeephaven","StockTrades")
    .where("Date=`2017-08-24`","USym=`GOOG`")
    .updateView("TimeBin=upperBin(Timestamp, 30 * MINUTE)")
    .where("isBusinessTime(TimeBin)")

plotXYStep = plot("GOOG", t7.where("USym = `GOOG`")
    .lastBy("TimeBin"), "TimeBin", "Last")
    .plotStyle("Step")
    .lineStyle(lineStyle(3))
    .show()
from deephaven import Plot

t7 = db.t("LearnDeephaven","StockTrades")\
    .where("Date=`2017-08-24`","USym=`GOOG`")\
    .updateView("TimeBin=upperBin(Timestamp, 30 * MINUTE)")\
    .where("isBusinessTime(TimeBin)")

plotXYStep = Plot.plot("GOOG", t7.where("USym = `GOOG`")\
    .lastBy("TimeBin"), "TimeBin", "Last")\
    .plotStyle("Step")\
    .lineStyle(Plot.lineStyle(3))\
    .show()

img

Additional Options