# Setting zmin and zmax to get a chosen z-range

## Missing functionality

Inspecting the `plot`

method of hyperplanes arrangement reveals
this is not implemented in Sage yet.

Searching Ask Sage and sage-support, we find that many 3d plotting
functions similarly lack the ability to limit the z-range. Providing this
missing functionality is now tracked at

## Workaround

Some of the questions on this theme were answered with a suggestion
to use implicit_plot3d. For hyperplanes, this works very well.

We can therefore mimic the `plot`

method of hyperplane arrangements
and cook up a function which, if given only an x-range and a y-range,
will simply call the `plot`

method (which adapts the z-range to the
full range of z values corresponding to the x-range and y-range), but
if additionally given a z-range, will use implicit plots to limit the z-range.

Here is such a function:

```
def ha_plot(A, ranges, **opt):
r"""
Return a plot of this hyperplane arrangement.
INPUT:
- ``A`` -- a hyperplane arrangement
- ``ranges`` -- a list consisting of an x-range, a y-range,
and optionally a z-range
"""
from colorsys import hsv_to_rgb
if len(ranges) == 2:
return A.plot(ranges=ranges, **opt)
elif len(ranges) != 3:
raise ValueError("ranges should consist in two or three tuples")
hh = [h.coefficients() for h in A.hyperplanes()]
N = len(hh)
HSV_tuples = [(i*1.0/N, 0.8, 0.9) for i in range(N)]
cols = [hsv_to_rgb(*x) for x in HSV_tuples]
ff = lambda a, b, c, d: lambda x, y, z: d + a*x + b*y + c*z
ip = lambda f, col: implicit_plot3d(f, *ranges, color=col, **opt)
hp = lambda a, b, c, d, col: ip(ff(a, b, c, d), col)
return sum(hp(a, b, c, d, col) for (d, a, b, c), col in zip(hh, cols))
```

Usage is as follows.

One can provide only an x-range and a y-range:

```
sage: ha_plot(A, [(-1, 1), (-1, 1)]).show(aspect_ratio=(1, 1, 0.25))
```

and get the exact same picture as in the question.

Or one can additionally provide a z-range:

```
sage: ha_plot(A, [(-1, 1), (-1, 1), (-1, 1)]).show(aspect_ratio=1)
```

Optional extra arguments are passed to `implicit_plot3d`

.

This for instance allows to set the opacity:

```
sage: ha_plot(A, [(-1, 1), (-1, 1), (-1, 1)], opacity=0.5).show(aspect_ratio=1)
```

The function could be improved to accept a choice of colours. Currently
it uses the same default as the `plot`

method of hyperplane arrangements.

## Solution using the `add_condition`

method of 3D plots

Added on 2021-08-01, inspired by @FrédéricC's answer to:

One could alternatively use the `add_condition`

method of 3D graphics objects.

One needs to pay attention to the fact that the plot of a hyperplane arrangement
is in fact the sum of the graphs of the individual hyperplanes.

The `add_condition`

method applies to each of those, rather than to their sum.

Define the hyperplane arrangement and name its plot:

```
H3.<x, y, z> = HyperplaneArrangements(QQ)
A = H3([(1, 2, 1), 0],
[(-4, -3, -2), 0],
[(3, 3, -2), 0],
[(1, -4, 3), 0],
[(-2, 2, 1), 0])
a = A.plot(ranges=[(-1, 1), (-1, 1)], aspect_ratio=(1, 1, 0.25))
```

Define bounds and sum the reworked plots
of individual arrangements truncated using `add_condition`

:

```
z_bounds = lambda x, y, z: -1 < z < 1
aa = sum(h.add_condition(z_bounds) for h in a.all)
```

Show the result:

```
aa
```