> ## Documentation Index
> Fetch the complete documentation index at: https://gocharting.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Color a plot by condition

> Plot the close and color it by a condition, soften the colors with color.new, and color it by a value with color.from_gradient.

In this tutorial we plot the closing price and color it per bar: first green where the close is above the previous close and red
where it is not, then with a smooth blend from red to green driven by the RSI. Every step is a whole script: replace what is in
the editor, and check it.

### 1. plot the close

```lipi theme={"languages":{"custom":["/languages/lipi.json","/languages/lipi-invalid.json"]}}
//@lipi=2
indicator("Rising close", "rising", overlay=true)
plot(close)
```

One line in the default color. `plot`'s `color` argument has a default and we have not passed one yet.

### 2. color it

`plot` takes a color, and the color may differ on every bar, so the test goes inside the argument. The conditional expression
`condition ? a : b` produces `a` when the condition holds and `b` when it does not.

```lipi theme={"languages":{"custom":["/languages/lipi.json","/languages/lipi-invalid.json"]}}
//@lipi=2
indicator("Rising close", "rising", overlay=true)
plot(close, color=close > close[1] ? color.green : color.red)
```

The line is green on every bar that closed above the bar before it and red on the rest. `close[1]` is the close one bar back.

### 3. name the condition

The plot call does two jobs. Move the test to its own line.

```lipi theme={"languages":{"custom":["/languages/lipi.json","/languages/lipi-invalid.json"]}}
//@lipi=2
indicator("Rising close", "rising", overlay=true)
bool up = close > close[1]
plot(close, color=up ? color.green : color.red)
```

The chart is identical; the script reads better.

### 4. soften the colors

`color.new(color, alpha)` returns the same color at a different opacity. Opacity runs from 0 to 1: 1 is solid and 0 is fully
transparent. Read it as how much of the color you want.

```lipi highlight={4} theme={"languages":{"custom":["/languages/lipi.json","/languages/lipi-invalid.json"]}}
//@lipi=2
indicator("Rising close", "rising", overlay=true)
bool up = close > close[1]
plot(close, color=up ? color.new(color.green, 0.5) : color.new(color.red, 0.5), linewidth=2)
```

The line is thicker and both colors are half strength, so the bars underneath show through.

A value outside 0 to 1 is clamped when the script runs, and a literal outside the range gets a warning from the editor. The usual
slip is to write a percentage: `color.new(color.red, 50)` warns `opacity 50 is outside 0–1; 1 is solid`. Write `0.5`.

### 5. color by a value

`color.from_gradient(value, bottom_value, top_value, bottom_color, top_color)` returns a color that blends from `bottom_color` to
`top_color` as `value` goes from `bottom_value` to `top_value`. A value below the bottom gives the bottom color and a value above
the top gives the top color; between them each channel, opacity included, is blended in proportion. The RSI runs from 0 to 100, so
30 and 70 make good ends.

```lipi theme={"languages":{"custom":["/languages/lipi.json","/languages/lipi-invalid.json"]}}
//@lipi=2
indicator("Close by RSI", "rsi color", overlay=true)
float rsi = talib.rsi(close, 14)
color shade = color.from_gradient(rsi, 30, 70, color.red, color.green)
plot(close, title="Close", color=shade, linewidth=2)
```

The line is red where the 14-bar RSI is 30 or lower, green at 70 or higher, and shades through the colors in between. If
`bottom_value` equals `top_value`, or any argument is `na`, the result is `na` (no color).

## The mistake to avoid

> [!WARNING]
>
> It is tempting to write the condition around the call:
>
> ```lipi-invalid theme={"languages":{"custom":["/languages/lipi.json","/languages/lipi-invalid.json"]}}
> //@lipi=2
> indicator("Rising close", "rising", overlay=true)
> if close > close[1] {
>     plot(close, color=color.green)
> }
> ```

The compiler says: `plot()` must be called in the global scope. The plot family has to be called at the top level of the script, so
the condition belongs in an argument, as in steps 2 to 5.

## What we built

An indicator that answers a question per bar in the color of the line. The shape to reuse: compute a `bool` or a number, then use it
inside `plot`'s color argument. The same shape colors the bars with `barcolor` and the background with `bgcolor` (see
[How to color bars by a condition](https://gocharting.com/docs/scripting/how-to/color-bars-by-a-condition.md)).

```lipi theme={"languages":{"custom":["/languages/lipi.json","/languages/lipi-invalid.json"]}}
//@lipi=2
indicator("Close by RSI", "rsi color", overlay=true)
float rsi = talib.rsi(close, 14)
color shade = color.from_gradient(rsi, 30, 70, color.red, color.green)
plot(close, title="Close", color=shade, linewidth=2)
```

## Next

> [card] [Color and transparency](https://gocharting.com/docs/scripting/chart-output/color.md)
>
> the color constants, `color.rgb` and `#RRGGBBAA` literals.

> [card] [Operators and expressions](https://gocharting.com/docs/scripting/language/expressions.md)
>
> the conditional expression and the other operators.

> [card] [Branching](https://gocharting.com/docs/scripting/language/branching.md)
>
> what `if` is for, given that it cannot wrap a plot.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.