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
\addplot3[surf,mark=none,mesh/cols=42,faceted color=black,
restrict z to domain=-0.2:0] file {ratio};
% Plane with transparency
\addplot3[surf,domain=0:9,samples=18,domain y=0:7,
samples y=14,opacity=0.5] {0};
% Bars above z = 0
\addplot3[surf,mark=none,mesh/cols=42,faceted color=black,
restrict z to domain=0:0.2] file {ratio};
\end{axis}
\end{tikzpicture}
Ratio $\zeta^\text{ele} / \zeta - \frac{5}{8}$
\end{center}
\end{document}
Beautiful result:
![enter image description here](https://i.stack.imgur.com/Xzwok.png)
Best Answer
The colormap in your right image is the PuYG colormap from the ColorBrewer website. PGFPlots contains a library that provides the colormaps from the website.
To use the colormaps, put
\usepgfplotslibrary{colorbrewer}
in the preamble and activate the desired colormap usingcolormap/PuYG
: