6

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}
    ]
    \addplot3[surf,mark=none,mesh/cols=16,faceted color=black] file {ratio};
    \end{axis}
\end{tikzpicture}

\end{document}

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

enter image description here

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?

1 Answer 1

4

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .