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?

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.