# Conditionally transparent surface in PGFPLOTS

I am plotting 3D bars using PGFPLOTS, following the example and using the script given by Anton in his answer (the second one) to this question: 3-dimensional histogram in pgfplots.

My code is the following:

\documentclass{minimal}

\usepackage{pgfplots}

\pgfplotsset{compat=1.9}

\begin{document}

\begin{tikzpicture}[scale=0.7]
\begin{axis}[
view = {120}{25},% important to draw x,y in increasing order
xmin = 0,
ymin = 0,
xmax = 9,
ymax = 7,
zmin = -0.20,
zmax = 0.20,
unbounded coords = jump,
point meta min=-0.2, point meta max=0.2,
colormap={pos}{color(0cm)=(blue); color(1cm)=(white); color(2cm)=(red)},
xtick={1.5,3.5,5.5,7.5}, xticklabels={N,P,As,Sb},
ytick={1.5,3.5,5.5}, yticklabels={Al,Ga,In},
ztick={-0.2,-0.1,0,0.1,0.2}
]
\end{axis}
\end{tikzpicture}

\end{document}


To run it you need this file called ratio. The output looks like this:

I would like to make the white surface (value z=0) transparent so I can see the blue bars for negative values. I can use the opacity= option to change the transparency of the whole plot, but I only want the white horizontal surface to be transparent. Schematically, this would be any correct equivalent of if (z == 0) then opacity = 0.5 ; else opacity = 1 ; fi. Can something like this be implemented?

Long answer to my own question after working a lot on it. This is a bit of a workaround rather than the proper answer (but it works nicely), so I will not accept it and leave the possibility for someone to actually answer how to make the opacity depend on the z value.

First, I edited Anton's python code in 3-dimensional histogram in pgfplots to remove the points I am not interested in:

import csv

def make3dhistogram(x, y, z, zmin, output):
writer = csv.writer(open(output, 'wb'), delimiter=' ')
for i in range(len(x)-1):
#
# Pre-row for closing faces
for j in range(len(y)-1):
writer.writerow((x[i], y[j], "nan"))
writer.writerow((x[i], y[j], zmin))
writer.writerow((x[i], y[j], zmin))
writer.writerow((x[i], y[j+1], zmin))
writer.writerow((x[i], y[j+1], zmin))
writer.writerow((x[i], y[j+1], "nan"))
writer.writerow([])
#
# Background side of 3D bars
for j in range(len(y)-1):
writer.writerow((x[i], y[j], "nan"))
writer.writerow((x[i], y[j], zmin))
writer.writerow((x[i], y[j], z[i][j]))
writer.writerow((x[i], y[j+1], z[i][j]))
writer.writerow((x[i], y[j+1], zmin))
writer.writerow((x[i], y[j+1], "nan"))
writer.writerow([])
#
# Foreground side of 3D bars
for j in range(len(y)-1):
writer.writerow((x[i+1], y[j], "nan"))
writer.writerow((x[i+1], y[j], zmin))
writer.writerow((x[i+1], y[j], z[i][j]))
writer.writerow((x[i+1], y[j+1], z[i][j]))
writer.writerow((x[i+1], y[j+1], zmin))
writer.writerow((x[i+1], y[j+1], "nan"))
writer.writerow([])

x = [0,1,2,3,4,5,6,7,8,9]
y = [0,1,2,3,4,5,6,7]
z = [["nan", "nan", "nan", "nan", "nan", "nan", "nan"],
["nan", 0.155, "nan", 0.105, "nan", 0.155, "nan"],
["nan", "nan", "nan", "nan", "nan", "nan", "nan"],
["nan", 0.005, "nan", -0.055, "nan", 0.005, "nan"],
["nan", "nan", "nan", "nan", "nan", "nan", "nan"],
["nan", -0.025, "nan", -0.095, "nan", -0.055, "nan"],
["nan", "nan", "nan", "nan", "nan", "nan", "nan"],
["nan", -0.045, "nan", -0.115, "nan", -0.085, "nan"],
["nan", "nan", "nan", "nan", "nan", "nan", "nan"]]
make3dhistogram(x, y, z, 0.0, 'ratio')


The script above now refers to auxiliary points with "nan". When run, it will create a file called ratio with the coordinates for the latex code. Now, I want to plot the plane at z = 0 and make it transparent. In order to achieve that, I plot (in this order) the bars below the plane, then the plane with transparency, and then the bars above the plane:

\documentclass[a4paper]{article}

\usepackage{amsmath}

\usepackage{pgfplots}
\usepackage[cm]{fullpage}
\pgfplotsset{compat=1.9}

\begin{document}
\thispagestyle{empty}

\begin{center}
\begin{tikzpicture}[scale=0.7]
\begin{axis}[
view = {120}{25},% important to draw x,y in increasing order
xmin = 0,
ymin = 0,
xmax = 9,
ymax = 7,
zmin = -0.20,
zmax = 0.20,
unbounded coords = jump,
point meta min=-0.2, point meta max=0.2,
colormap={pos}{color(0cm)=(blue); color(1cm)=(white); color(2cm)=(red)},
xtick={1.5,3.5,5.5,7.5}, xticklabels={N,P,As,Sb},
ytick={1.5,3.5,5.5}, yticklabels={Al,Ga,In},
ztick={-0.2,-0.1,0,0.1,0.2}
]
% Bars below z = 0
restrict z to domain=-0.2:0] file {ratio};
% Plane with transparency
samples y=14,opacity=0.5] {0};
% Bars above z = 0
Ratio $\zeta^\text{ele} / \zeta - \frac{5}{8}$