# Layer plots

To “layer” or “stack” multiple plots on top of each other, use the `layer` function. This is useful if you want to combine multiple plots of different types into a single visualization, such as a [scatter plot](scatter.md) and a [line plot](line.md). This is distinct from [sub-plots](sub-plots.md), which present multiple plots side-by-side. By default, the stacked plot will use the layout (axis labels, axis ranges, and title) from the last plot in the sequence. The `which_layout` parameter can be used to specify which plot’s layout should be used.

## Examples

### Layering two plots

Use a [candlestick plot](candlestick.md) and a [line plot](line.md) for two different perspectives on the same data.

```python order=financial_plot,dog_prices,dog_ohlc,stocks
import deephaven.plot.express as dx
import deephaven.agg as agg
stocks = dx.data.stocks()  # import the example stock market data set

# select only DOG prices and compute ohlc
dog_prices = stocks.where("Sym == `DOG`")
dog_ohlc = dog_prices.update_view(
    "BinnedTimestamp = lowerBin(Timestamp, 'PT1m')"
).agg_by(
    [
        agg.first("Open=Price"),
        agg.max_("High=Price"),
        agg.min_("Low=Price"),
        agg.last("Close=Price"),
    ],
    by="BinnedTimestamp",
)

# layer a line plot and a candlestick plot by passing both to layer()
financial_plot = dx.layer(
    dx.line(
        dog_prices, x="Timestamp", y="Price"),
    dx.candlestick(
        dog_ohlc, x="BinnedTimestamp",
        open="Open", high="High", low="Low", close="Close")
)
```

## API Reference

Layers the provided figures. Be default, the layouts are sequentially
applied, so the layouts of later figures will override the layouts of early
figures.

**Returns:** `DeephavenFigure` The layered chart

<ParamTable param={{"module_name": "deephaven.plot.express.", "name": "layer", "parameters": [{"name": "*figs", "type": "DeephavenFigure | Figure", "description": "The charts to layer"}, {"name": "which_layout", "type": "int | None", "description": "None to layer layouts, or an index of which arg to take the layout from. Currently only valid if domains are not specified.", "default": "None"}, {"name": "specs", "type": "list[LayerSpecDict] | None", "description": "A list of dictionaries that contains keys of \"x\" and \"y\" that have values that are lists of two floats from 0 to 1. The chart that corresponds with a domain will be resized to that domain. Either x or y can be excluded if only resizing on one axis. Can also specify \"xaxis_update\" or \"yaxis_update\" with a dictionary value to update all axes with that dict. Can also specify \"matched_xaxis\" or \"matched_yaxis\" to add this figure to a match group. All figures with the same value of this group will have matching axes.", "default": "None"}, {"name": "unsafe_update_figure", "type": "Callable", "description": "An update function that takes a plotly figure as an argument and optionally returns a plotly figure. If a figure is not returned, the plotly figure passed will be assumed to be the return value. Used to add any custom changes to the underlying plotly figure. Note that the existing data traces should not be removed. This may lead to unexpected behavior if traces are modified in a way that break data mappings.", "default": "<function default_callback>"}]}} />
