Plotting with Plot(): Styles, Colours and Panes
Everything you have ever seen on an AmiBroker chart arrived there through a handful of
drawing functions, and Plot() is the one that does almost all the work. Learn its nine
arguments properly and you stop guessing why a line is the wrong colour, in the wrong pane,
or hidden behind something else.
This lesson is the reference you will come back to. It is deliberately dense in places, because the argument order and the constant names are exactly the things you cannot invent.
The nine arguments
Section titled “The nine arguments”The documented signature is:
Fragment — not a complete formula
Plot( array, name, color, style = styleLine, minvalue = {empty}, maxvalue = {empty}, XShift = 0, ZOrder = 0, width = 1 );Three of the nine are required — array, name and color — and the official tutorial
says so in those words. The rest have defaults, and the defaults are usually what you want.
| # | Argument | What it does |
|---|---|---|
| 1 | array |
The series to draw. One value per bar. |
| 2 | name |
The label used for this plot in the chart title bar. |
| 3 | color |
A single colour number, or an array of colour numbers, one per bar. |
| 4 | style |
A combination of style* flags. Default styleLine. |
| 5 | minvalue |
Lower Y bound. Documented as used by styleOwnScale plots only. |
| 6 | maxvalue |
Upper Y bound. Same restriction. |
| 7 | XShift |
Shifts the drawing horizontally by N bars. Visual only. |
| 8 | ZOrder |
Front/back position. 0 is where the grid sits. |
| 9 | width |
Positive: pixels. Negative: percent of bar width. |
Two of those deserve immediate attention.
color accepting an array is the single most useful fact in the whole drawing layer. It is
why one Plot() call can produce a line that is green while an average is rising and red
while it is falling — you build a colour array with IIf() and pass it in the third slot.
XShift is purely cosmetic. The official example is explicit that the shift happens during
plotting and does not affect the source array. Shifting a plot to the right does not make
the underlying calculation look into the future; it makes the picture lie about when the
value existed, which is a different and arguably worse problem.
Filling slots you do not want
Section titled “Filling slots you do not want”AFL has no named arguments. To reach the eighth slot you must fill the fourth through
seventh, and the convention for “leave this alone” is Null:
Fragment — not a complete formula
// array, name, color, style, minvalue, maxvalue, XShift, ZOrderPlot( Close, "Price", colorDefault, styleCandle, Null, Null, 0, 1 );PlotOHLC() makes this worse by design: its name argument is the fifth and its color
the sixth, because four arrays come first. Copying a Plot() argument list across to
PlotOHLC() and hoping is a reliable way to lose an afternoon.
Style constants
Section titled “Style constants”Styles are bit flags. Combine them with | (binary OR) or +.
| Constant | Value | Effect |
|---|---|---|
styleLine |
1 | Line chart — the default |
styleHistogram |
2 | Histogram |
styleThick |
4 | Thick |
styleDots |
8 | Include dots |
styleNoLine |
16 | No line |
styleDashed |
32 | Dashed |
styleCandle |
64 | Candlesticks |
styleBar |
128 | Traditional bars |
styleNoDraw |
256 | Not drawn, but still scales the axis |
styleStaircase |
512 | Staircase |
styleSwingDots |
1024 | Middle dots for staircase |
styleNoRescale |
2048 | Excluded from Y-axis autoscaling |
styleNoLabel |
4096 | No value label on the axis |
stylePointAndFigure |
8192 | Point and figure |
styleArea |
16384 | Area (wide histogram) |
styleOwnScale |
32768 | Independent Y scale |
styleLeftAxisScale |
65536 | Uses the left axis, independent of the right |
styleNoTitle |
131072 | Keeps this plot out of the title string |
styleCloud |
262144 | Filled cloud — intended for PlotOHLC() |
styleClipMinMax |
524288 | Clips the painted area to the min/max levels |
styleGradient |
— | Gradient area fill; pairs with SetGradientFill() |
styleHidden |
— | Not drawn, but the values reach the Data window |
The numeric values for styleGradient and styleHidden are not published in the official
guide, which does not matter: the documentation tells you to use the names, and the names are
what the course validator checks.
Not every combination is meaningful. The documentation’s own example is
styleCandle | styleLine, which simply resolves to a candlestick. There is also a genuine
historical trap: the value 32 is styleDashed in Plot(), but the same value is documented
as styleLog in the obsolete graphNstyle table. For modern code, 32 means dashed;
logarithmic scaling is a chart option, not a plot style.
The four ways to not draw something
Section titled “The four ways to not draw something”These are frequently confused, and they do four different jobs:
styleNoDraw— nothing is drawn, but the series still takes part in Y-axis scaling. This is how you reserve room for a series you are about to shift into view.styleHidden— nothing is drawn and the values appear in the Data window and the data tooltip. This is how you inspect an intermediate calculation without adding a line.styleNoLabel— the line is drawn, but no value label appears on the axis.styleNoTitle— the line is drawn, but its value is left out of the title string. You want this on every plot in a formula that writes its ownTitle.
Colours
Section titled “Colours”AmiBroker’s colour argument accepts three different kinds of value, and they share one numeric space.
The named palette runs from index 0 to 55. Indexes 16 to 55 are fixed names —
colorBlack, colorRed, colorBrightGreen, colorPaleTurquoise and so on. Indexes 0 to
15 are colorCustom1 through colorCustom16, and those are user-editable in
Tools → Preferences → Colors.
For anything outside the palette there is ColorRGB( red, green, blue ) with each component
in the range 0–255, and ColorHSB( hue, saturation, brightness ) with all three in the
range 0–255. The hue range is the trap: it is 0–255, not 0–360, so passing degrees wraps in
ways that look like a bug in your maths.
ColorBlend( colorFrom, colorTo, factor ) mixes two colours, with factor defaulting to
0.5. A factor of 0 gives you colorFrom only and a factor of 1 gives colorTo only, which
is the opposite of what most people guess the first time. The official page publishes the two
helpers everyone ends up writing anyway: lightening is a blend towards colorWhite,
darkening a blend towards colorBlack.
GetChartBkColor() returns the pane’s current background colour, which is how you write a
formula that stays legible in both a light and a dark theme. You can pass the returned value
straight back into another colour argument. If you want the actual red, green and blue
components you must first subtract 56, because the 24-bit values are offset by the number of
predefined palette colours.
Colour as an array
Section titled “Colour as an array”This is where the third argument earns its keep:
Fragment — not a complete formula
BarTint = IIf( Close >= Open, colorGreen, colorRed );Plot( Close, "Price", BarTint, styleCandle );A colour argument is just another array
| Bar | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
Close | 10.0 | 11.0 | 10.5 | 11.5 | 11.2 |
Open | 9.8 | 10.2 | 11.0 | 10.6 | 11.4 |
Close >= Open | 1 | 1 | 0 | 1 | 0 |
BarTint | green | green | red | green | red |
SetBarFillColor() gives you a second, independent colour for the interior of candles,
bars, areas and clouds, with the outline still coming from Plot(). It must be called
before the Plot() it applies to, and it affects only those four styles — calling it
before a styleLine plot does nothing at all.
Scaling: shared, own and left
Section titled “Scaling: shared, own and left”By default every plot in a pane shares one Y scale, computed from all of them together. That is what you want for price and its moving averages, and completely wrong for price and volume, whose numbers differ by orders of magnitude.
styleOwnScale gives a plot its own independent Y range. On its own that range is chosen
automatically; supplying minvalue and maxvalue is how you control it. This is the only
documented situation in which those two arguments do anything — passing them to an ordinary
plot does not rescale the pane.
Two useful consequences follow.
First, if you give two own-scale plots the same explicit minvalue and maxvalue, they
share a scale with each other while remaining independent of everything else in the pane.
Second, choosing bounds deliberately lets you place a series in a slice of the pane. The official ribbon idiom does exactly this: plot the constant 2 with a scale running from −0.5 to 100, and the result is a band two per cent of the pane’s height sitting at its foot.
Fragment — not a complete formula
// The plotted constant is the ribbon's height as a percentage of pane height.Plot( 2, "Ribbon", IIf( Trend, colorGreen, colorRed ), styleOwnScale | styleArea | styleNoLabel, -0.5, 100 );styleLeftAxisScale is the third option: the plot is scaled against the left axis,
independently of the right. It is the natural home for a secondary series that deserves a
readable axis of its own rather than an invisible one.
styleNoRescale is different again and often confused with styleNoLabel. It excludes a
plot from the pane’s autoscaling, so a reference line that occasionally runs far away cannot
squash everything else flat.
Panes and overlays
Section titled “Panes and overlays”A “pane” is one horizontal strip of a chart window; a chart window is a stack of panes. Every
Plot() in a formula draws into the pane that formula was applied to. There is no argument
that moves a plot to a different pane, and no way for one formula to draw into two panes.
That gives you exactly two choices, and they are made in the user interface rather than in the code:
- Overlay — drag the formula from the Charts window onto an existing pane. Its plots join whatever is already there and, unless you ask otherwise, share that pane’s Y scale.
- Separate pane — drop the formula on empty chart space, or use Insert. It gets its own strip and its own scale.
An indicator whose values live on the price scale — moving averages, bands, pivots — belongs
as an overlay. An indicator with its own natural range — RSI, ATR, a percentile — belongs in
its own pane, where the 0–100 axis is readable. The one thing you should not do is force a
0–100 oscillator onto a price pane with styleOwnScale and then wonder why nobody can read
the values.
Layering
Section titled “Layering”Within a pane, ZOrder decides what is in front. The number to remember is that the grid
sits at ZOrder 0, so a plot needs a negative ZOrder to be drawn behind the grid lines.
Within a single ZOrder layer, drawing order is the reverse of call order: the last
Plot() in the file is drawn first, and therefore furthest back. This is the answer to
“why is my second plot hidden behind my first one?”. Setting GraphZOrder = 1; flips the
ordering back to call order, and an explicit ZOrder argument always wins over both.
Two more chart-level variables belong here. GraphXSpace = 5; adds five per cent of extra
room above and below the graph — despite the X in the name, it controls vertical space,
and its default when unset is 2%. And GraphLabelDecimals = 2; sets the number of decimal
places in the axis value labels, which does not affect anything in your Title string.
Putting it together
Section titled “Putting it together”What we are building
Section titled “What we are building”A single price pane that demonstrates every mechanism above at once: conditional bar colour, a candle interior separate from its outline, a moving average layered in front, a volume band pinned to the bottom fifth of the pane on its own scale and behind the grid, an intermediate series that is calculated but never drawn, and a grid line at the average’s current level.
The formula
Section titled “The formula”Complete runnable AFL
/* * Plot styles, scales and layers - worked example for Part 10. * * Assumptions * - Chart pane formula. Apply it to the price pane, or insert it as its own * pane; the same code works in both places, it simply looks different. * - Any interval, any symbol. Symbols with no volume data draw an empty * volume band rather than failing. * - Nothing here is a trading rule. The formula exists to make the drawing * mechanics visible: argument slots, own scaling, layering and hiding. */
_SECTION_BEGIN( "Price and layers" );
// GraphXSpace is a percentage of extra room added ABOVE AND BELOW the graph.// The default when it is not set is 2%.GraphXSpace = 6;
// A per-bar colour array. Plot()'s third argument accepts either a single// colour number or one colour per bar, which is where conditional colouring// comes from.BarTint = IIf( Close >= Open, ParamColor( "Up bar", colorGreen ), ParamColor( "Down bar", colorRed ) );
// SetBarFillColor must PRECEDE the Plot() it applies to, and it only affects// styleCandle, styleBar, styleArea and styleCloud. Here it fills the candle// bodies while the outline keeps the colour passed to Plot().SetBarFillColor( ColorBlend( BarTint, GetChartBkColor(), 0.55 ) );
// Argument slots, in documented order:// array, name, color, style, minvalue, maxvalue, XShift, ZOrder, widthPlot( Close, "Price", BarTint, ParamStyle( "Price style", styleCandle, maskPrice ) | GetPriceStyle(), Null, Null, 0, 1 );
MaPeriod = Param( "MA periods", 50, 2, 400, 1 );
// ZOrder 2 puts this line in front of the price plot. Within one ZOrder layer// the LAST Plot() call is drawn FIRST, i.e. furthest back, so relying on call// order alone is how plots end up hidden behind each other.Plot( MA( Close, MaPeriod ), "MA " + NumToStr( MaPeriod, 1.0 ), ParamColor( "MA colour", colorBlue ), styleLine | styleThick, Null, Null, 0, 2 );
// A volume band pinned to the bottom of the pane. minvalue/maxvalue are// documented as being used by styleOwnScale plots only; setting the ceiling to// five times the tallest recent bar keeps volume inside the lowest fifth of the// pane. ZOrder -1 draws it behind the grid, because ZOrder 0 is where the grid// itself sits.VolumeCeiling = Max( 5 * LastValue( HHV( Volume, 250 ) ), 1 );
Plot( Volume, "Volume", ColorBlend( ParamColor( "Volume colour", colorBlueGrey ), GetChartBkColor(), 0.5 ), styleArea | styleOwnScale | styleNoLabel | styleNoTitle, 0, VolumeCeiling, 0, -1 );
// Not drawn at all, but the values are available in the Data window and the// data tooltip. This is how you inspect an intermediate series without adding// another line to an already busy chart.Distance = 100 * ( Close - MA( Close, MaPeriod ) ) / MA( Close, MaPeriod );Plot( Distance, "Distance from MA (%)", colorDefault, styleHidden );
// A constant level is cheaper to draw with PlotGrid than with Plot, and the// official guide recommends it explicitly. Pattern 10 is a solid line.PlotGrid( LastValue( MA( Close, MaPeriod ) ), colorGrey40, 10, 1, False );
_SECTION_END();How it works
Section titled “How it works”The formula falls into four movements.
It begins by opening a section and setting GraphXSpace, so that nothing is drawn hard
against the pane edges. Then it builds BarTint, a colour array, and hands it to
SetBarFillColor() in a blended, lightened form — blending the bar colour halfway towards
the pane’s own background is what keeps the interior legible whether the user runs a light or
a dark theme.
The price plot combines ParamStyle() with GetPriceStyle(), which is the idiom AmiBroker’s
own price formula uses: the Parameters-dialog choice and the View → Price chart style menu
are OR-ed together, so both work rather than one overriding the other.
The moving average is plotted at ZOrder 2 while price sits at ZOrder 1, which puts the
line in front of the candles regardless of the order the two calls appear in.
The volume band is the interesting part. It is an area plot with its own scale, running from
0 to five times the tallest volume bar of the last 250. Because the ceiling is five times the
peak, the tallest bar reaches one fifth of the pane height. ZOrder -1 puts the whole band
behind the grid so it reads as background rather than as data competing with price. The
Max( ..., 1 ) guard exists because a symbol with no volume data would otherwise produce a
scale whose minimum and maximum are both zero.
Finally, Distance is calculated and plotted with styleHidden, so it never appears on the
chart but does appear in the Data window, and PlotGrid() draws a single horizontal line at
the average’s most recent value.
Key functions
Section titled “Key functions”SetBarFillColor( colorarray )— sets the interior colour of candles, bars, areas and clouds. Must precede thePlot()it applies to.GetChartBkColor()— returns the pane’s background colour, so a formula can adapt to the user’s theme.ColorBlend( from, to, factor )— mixes two colours;factorruns from 0 (allfrom) to 1 (allto).GetPriceStyle()— returns the price style chosen in View → Price chart style, ready to be OR-ed into a style argument.PlotGrid( level, color, pattern, width, Label )— draws a horizontal reference line through the grid-drawing path.levelmust be a number.
What you should see
Section titled “What you should see”A candle chart in which up bars and down bars have different outline colours and paler interiors, a thick moving-average line drawn on top of the candles, a soft volume histogram occupying roughly the bottom fifth of the pane and sitting behind the grid, and one solid horizontal line at the current value of the average. Hovering a bar and opening the Data window shows a “Distance from MA (%)” row that has no corresponding line on the chart.
Test it
Section titled “Test it”- Change MA periods in the Parameters dialog and confirm the line, the grid line and the hidden Data-window row all move together. If the grid line lags, you have two different period values in the formula.
- Temporarily change the volume plot’s
ZOrderfrom-1to1and redraw. The volume band should jump in front of the grid lines. Put it back. - Delete
styleOwnScalefrom the volume plot. The pane’s Y axis should collapse, because volume in the millions is now sharing a scale with price in the tens. This is the failure the own scale exists to prevent. - Apply the formula to a symbol with no volume — a currency cross, or an index. The volume band should be empty and everything else should still draw.
Common errors
Section titled “Common errors”- The volume band fills the whole pane. The
minvalue/maxvaluearguments landed in the wrong slots. Count the commas: style is fourth, min is fifth, max is sixth. - Nothing changes when you edit a colour. You edited a
colorCustom*slot rather than the formula, or the parameter you changed belongs to a different chart pane — parameter values are stored per chart, which the parameters lesson covers. styleHiddenstill draws a line. Check you have not also passed a style that forces drawing, and remember that the Data-window row only appears when the Data window is open.- The moving average disappears at the left edge. That is
MA()returningNullfor its firstperiods - 1bars, which is correct behaviour and not a plotting fault.
Extension
Section titled “Extension”Add a second moving average on styleLeftAxisScale and give it a period far from the first —
say 5 and 200. Watch what the left axis does, then decide whether a second axis genuinely
helps a reader or simply makes two unrelated lines look comparable. That judgement is the
real content of this lesson.
What changed
Section titled “What changed”You now know what all nine Plot() arguments do, which two of them only work with an own
scale, the documented names of the style and colour constants, and the three ways a plot can
be present without being visible. You also know that panes are chosen in the interface rather
than in code, and that layering is decided by ZOrder first and call order second — in
reverse.
The next lesson takes the other half of the pane: the title bar, and the numbers you want it to report.
Check your understanding
Sources for this lesson
6 verified · checked 2026-08-31
- 01AFL Function Reference — Plotamibroker.com/guide/afl/plot.html2026-08-31
- 02AmiBroker User's Guide — Creating your own indicators, part 2 (styles, colours, titles)amibroker.com/guide/h_indbuilder2.html2026-08-31
- 03AFL Function Reference — PlotGridamibroker.com/guide/afl/plotgrid.html2026-08-31
- 04AFL Function Reference — SetBarFillColoramibroker.com/guide/afl/setbarfillcolor.html2026-08-31
- 05AFL Function Reference — ColorRGBamibroker.com/guide/afl/colorrgb.html2026-08-31
- 06AFL Function Reference — GetChartBkColoramibroker.com/guide/afl/getchartbkcolor.html2026-08-31
Every technical claim on this page was checked against the official AmiBroker documentation on the date shown. Where the course disagrees with folklore, the source is how you can tell which one to trust.