Skip to content

Instantly share code, notes, and snippets.

@timothymillar
Created December 22, 2023 02:20
Show Gist options
  • Save timothymillar/8ebb2e7a8a60e2d0872b7af7cafc11af to your computer and use it in GitHub Desktop.
Save timothymillar/8ebb2e7a8a60e2d0872b7af7cafc11af to your computer and use it in GitHub Desktop.
Zarr-sgkit-figure
\documentclass{article}
\usepackage{forest}
\usepackage{tikz}
\usetikzlibrary{quotes,arrows.meta,3d}
\title{Zarr-sgkit}
\author{Tim Millar}
\date{December 2023}
%% flexible cuboid from
%% https://tex.stackexchange.com/questions/267982/tikz-easy-drawing-of-cuboids
\makeatletter
\def\tikz@lib@cuboid@get#1{\pgfkeysvalueof{/tikz/cuboid/#1}}
\def\tikz@lib@cuboid@setup{%
\pgfmathsetlengthmacro{\vxx}%
{\tikz@lib@cuboid@get{xscale}*cos(\tikz@lib@cuboid@get{xangle})*1cm}
\pgfmathsetlengthmacro{\vxy}%
{\tikz@lib@cuboid@get{xscale}*sin(\tikz@lib@cuboid@get{xangle})*1cm}
\pgfmathsetlengthmacro{\vyx}%
{\tikz@lib@cuboid@get{yscale}*cos(\tikz@lib@cuboid@get{yangle})*1cm}
\pgfmathsetlengthmacro{\vyy}%
{\tikz@lib@cuboid@get{yscale}*sin(\tikz@lib@cuboid@get{yangle})*1cm}
\pgfmathsetlengthmacro{\vzx}%
{\tikz@lib@cuboid@get{zscale}*cos(\tikz@lib@cuboid@get{zangle})*1cm}
\pgfmathsetlengthmacro{\vzy}%
{\tikz@lib@cuboid@get{zscale}*sin(\tikz@lib@cuboid@get{zangle})*1cm}
}
\def\tikz@lib@cuboid@draw#1--#2--#3\pgf@stop{%
\begin{scope}[join=bevel,x={(\vxx,\vxy)},y={(\vyx,\vyy)},z={(\vzx,\vzy)}]
% first fill the faces with global and individual style
% then draw the grids
\begin{scope}[canvas is yz plane at x=#1]
\draw[cuboid/all faces,cuboid/edges,cuboid/right face]
(0,0) -- ++(#2,0) -- ++(0,-#3) -- ++(-#2,0) -- cycle;
\draw[cuboid/all grids,cuboid/right grid] (0,0) grid (#2,-#3);
\end{scope}
\begin{scope}[canvas is xy plane at z=0]
\draw[cuboid/all faces,cuboid/edges,cuboid/front face]
(0,0) -- ++(#1,0) -- ++(0,#2) -- ++(-#1,0) -- cycle;
\draw[cuboid/all grids,cuboid/front grid] (0,0) grid (#1,#2);
\end{scope}
\begin{scope}[canvas is xz plane at y=#2]
\draw[cuboid/all faces,cuboid/edges,cuboid/top face]
(0,0) -- ++(#1,0) -- ++(0,-#3) -- ++(-#1,0) -- cycle;
\draw[cuboid/all grids,cuboid/top grid] (0,0) grid (#1,-#3);
\end{scope}
% now, draw the hidden edges
\draw[cuboid/hidden edges] (0,#2,-#3) -- (0,0,-#3) -- (0,0,0)
(0,0,-#3) -- ++(#1,0,0);
% finally, draw the visible edges
\begin{scope}[canvas is yz plane at x=#1]
\draw[cuboid/all faces,cuboid/right face,cuboid/edges,fill opacity=0]
(0,0) -- ++(#2,0) -- ++(0,-#3) -- ++(-#2,0) -- cycle;
\end{scope}
\begin{scope}[canvas is xy plane at z=0]
\draw[cuboid/all faces,cuboid/front face,cuboid/edges,fill opacity=0]
(0,0) -- ++(#1,0) -- ++(0,#2) -- ++(-#1,0) -- cycle;
\end{scope}
\begin{scope}[canvas is xz plane at y=#2]
\draw[cuboid/all faces,cuboid/top face,cuboid/edges,fill opacity=0]
(0,0) -- ++(#1,0) -- ++(0,-#3) -- ++(-#1,0) -- cycle;
\end{scope}
% define the anchors: 8 vertices
\path (0,#2,0) coordinate (-left top front)
coordinate (-left front top)
coordinate (-top left front)
coordinate (-top front left)
coordinate (-front top left)
coordinate (-front left top);
\path (0,#2,-#3) coordinate (-left top rear)
coordinate (-left rear top)
coordinate (-top left rear)
coordinate (-top rear left)
coordinate (-rear top left)
coordinate (-rear left top);
\path (0,0,-#3) coordinate (-left bottom rear)
coordinate (-left rear bottom)
coordinate (-bottom left rear)
coordinate (-bottom rear left)
coordinate (-rear bottom left)
coordinate (-rear left bottom);
\path (0,0,0) coordinate (-left bottom front)
coordinate (-left front bottom)
coordinate (-bottom left front)
coordinate (-bottom front left)
coordinate (-front bottom left)
coordinate (-front left bottom);
\path (#1,#2,0) coordinate (-right top front)
coordinate (-right front top)
coordinate (-top right front)
coordinate (-top front right)
coordinate (-front top right)
coordinate (-front right top);
\path (#1,#2,-#3) coordinate (-right top rear)
coordinate (-right rear top)
coordinate (-top right rear)
coordinate (-top rear right)
coordinate (-rear top right)
coordinate (-rear right top);
\path (#1,0,-#3) coordinate (-right bottom rear)
coordinate (-right rear bottom)
coordinate (-bottom right rear)
coordinate (-bottom rear right)
coordinate (-rear bottom right)
coordinate (-rear right bottom);
\path (#1,0,0) coordinate (-right bottom front)
coordinate (-right front bottom)
coordinate (-bottom right front)
coordinate (-bottom front right)
coordinate (-front bottom right)
coordinate (-front right bottom);
% centers of the 6 faces
\coordinate (-left center) at (0,.5*#2,-.5*#3);
\coordinate (-right center) at (#1,.5*#2,-.5*#3);
\coordinate (-top center) at (.5*#1,#2,-.5*#3);
\coordinate (-bottom center) at (.5*#1,0,-.5*#3);
\coordinate (-front center) at (.5*#1,.5*#2,0);
\coordinate (-rear center) at (.5*#1,.5*#2,-#3);
% center of the cuboid
\coordinate (-center) at (.5*#1,.5*#2,-.5*#3);
% centers of the 12 edges
\path (0,#2,-.5*#3) coordinate (-left top center)
coordinate (-top left center);
\path (.5*#1,#2,-#3) coordinate (-top rear center)
coordinate (-rear top center);
\path (#1,#2,-.5*#3) coordinate (-right top center)
coordinate (-top right center);
\path (.5*#1,#2,0) coordinate (-top front center)
coordinate (-front top center);
\path (0,0,-.5*#3) coordinate (-left bottom center)
coordinate (-bottom left center);
\path (.5*#1,0,-#3) coordinate (-bottom rear center)
coordinate (-rear bottom center);
\path (#1,0,-.5*#3) coordinate (-right bottom center)
coordinate (-bottom right center);
\path (.5*#1,0,0) coordinate (-bottom front center)
coordinate (-front bottom center);
\path (0,.5*#2,0) coordinate (-left front center)
coordinate (-front left center);
\path (0,.5*#2,-#3) coordinate (-left rear center)
coordinate (-rear left center);
\path (#1,.5*#2,0) coordinate (-right front center)
coordinate (-front right center);
\path (#1,.5*#2,-#3) coordinate (-right rear center)
coordinate (-rear right center);
\end{scope}
}
\tikzset{
pics/cuboid/.style = {
setup code = \tikz@lib@cuboid@setup,
background code = \tikz@lib@cuboid@draw#1\pgf@stop
},
pics/cuboid/.default={1--1--1},
cuboid/.is family,
cuboid,
all faces/.style={fill=white},
all grids/.style={draw=none},
front face/.style={},
front grid/.style={},
right face/.style={},
right grid/.style={},
top face/.style={},
top grid/.style={},
edges/.style={},
hidden edges/.style={draw=none},
xangle/.initial=0,
yangle/.initial=90,
zangle/.initial=210,
xscale/.initial=1,
yscale/.initial=1,
zscale/.initial=0.5
}
\newcommand{\tikzcuboidreset}{
\tikzset{cuboid,
all faces/.style={fill=white},
all grids/.style={draw=none},
front face/.style={},
front grid/.style={},
right face/.style={},
right grid/.style={},
top face/.style={},
top grid/.style={},
edges/.style={},
hidden edges/.style={draw=none},
xangle=0,
yangle=90,
zangle=225,
xscale=1,
yscale=1,
zscale=0.5
}
}
\newcommand{\tikzcuboidset}{\@ifstar\tikzcuboidset@star\tikzcuboidset@nostar}
\newcommand{\tikzcuboidset@nostar}[1]{\tikzcuboidreset\tikzset{cuboid,#1}}
\newcommand{\tikzcuboidset@star}[1]{\tikzset{cuboid,#1}}
\makeatother
\begin{document}
\maketitle
\begin{tikzpicture}
%% sample_id
\node at (2.0,6.6,-.5) {\ttfamily \scriptsize sample\textunderscore id};
% bounds
\draw[densely dashed] (0,6.2,-.5) -- (3.9,6.2,-.5);
\draw[densely dashed] (0,6.4,-.5) -- (3.9,6.4,-.5);
\tikzcuboidset{front face/.style={fill=yellow!20},right face/.style={fill=green!10},top face/.style={fill=yellow!20}}
\pic at (0,6.2,-.5) {cuboid=.9--.2--0};
\pic at (1,6.2,-.5) {cuboid=.9--.2--0};
\node at (2.5,6.3,-.5) {\ttfamily \dots};
\pic at (3,6.2,-.5) {cuboid=.9--.2--0};
%% sample_cohort
\node at (2.0,5.9,-.5) {\ttfamily \scriptsize sample\textunderscore cohort};
% bounds
\draw[densely dashed] (0,5.5,-.5) -- (3.9,5.5,-.5);
\draw[densely dashed] (0,5.7,-.5) -- (3.9,5.7,-.5);
\tikzcuboidset{front face/.style={fill=yellow!20},right face/.style={fill=green!10},top face/.style={fill=yellow!20}}
\pic at (0,5.5,-.5) {cuboid=.9--.2--0};
\pic at (1,5.5,-.5) {cuboid=.9--.2--0};
\node at (2.5,5.6,-.5) {\ttfamily \dots};
\pic at (3,5.5,-.5) {cuboid=.9--.2--0};
%% variant_contig
\node[rotate=90] at (-1.5,2.5,-.3) {\ttfamily \scriptsize variant\textunderscore contig};
% bounds
\draw[densely dashed] (-1.4,0,-.5) -- (-1.4,4.9,-.5);
\draw[densely dashed] (-1.2,0,-.5) -- (-1.2,4.9,-.5);
\tikzcuboidset{front face/.style={fill=green!10},right face/.style={fill=green!10},top face/.style={fill=yellow!20}}
\pic at (-1.4,0,-.5) {cuboid=.2--.9--0};
\node at (-1.3,1.5,-.5) {\ttfamily \vdots};
\pic at (-1.4,2,-.5) {cuboid=.2--.9--0};
\pic at (-1.4,3,-.5) {cuboid=.2--.9--0};
\pic at (-1.4,4,-.5) {cuboid=.2--.9--0};
%% variant_position
\node[rotate=90] at (-.8,2.5,-.3) {\ttfamily \scriptsize variant\textunderscore position};
% bounds
\draw[densely dashed] (-.7,0,-.5) -- (-.7,4.9,-.5);
\draw[densely dashed] (-.5,0,-.5) -- (-.5,4.9,-.5);
\tikzcuboidset{front face/.style={fill=green!10},right face/.style={fill=green!10},top face/.style={fill=yellow!20}}
\pic at (-.7,0,-.5) {cuboid=.2--.9--0};
\node at (-.6,1.5,-.5) {\ttfamily \vdots};
\pic at (-.7,2,-.5) {cuboid=.2--.9--0};
\pic at (-.7,3,-.5) {cuboid=.2--.9--0};
\pic at (-.7,4,-.5) {cuboid=.2--.9--0};
%% call_genotype
\node at (2.0,5.3) {\ttfamily \scriptsize call\textunderscore genotype};
% back box
\draw[densely dashed] (0,0,-0.5) -- (3.9,0,-0.5);
\draw[densely dashed] (0,0,-0.5) -- (0,4.9,-0.5);
\draw[densely dashed] (0,4.9,-0.5) -- (3.9,4.9,-0.5);
\draw[densely dashed] (3.9,0,-0.5) -- (3.9,4.9,-0.5);
\tikzcuboidset{front face/.style={fill=blue!10},right face/.style={fill=green!10},top face/.style={fill=yellow!20}}
\pic at (0,0) {cuboid=.9--.9--.5};
\node at (0.45,0.5) {\ttfamily \tiny 100.0.0};
\node at (0.5,1.6) {\ttfamily \vdots};
\pic at (0,2) {cuboid=.9--.9--.5};
\node at (0.45,2.5) {\ttfamily \tiny 2.0.0};
\pic at (0,3) {cuboid=.9--.9--.5};
\node at (0.45,3.5) {\ttfamily \tiny 1.0.0};
\pic at (0,4) {cuboid=.9--.9--.5};
\node at (0.45,4.5) {\ttfamily \tiny 0.0.0};
\pic at (1,0) {cuboid=.9--.9--.5};
\node at (1.45,0.5) {\ttfamily \tiny 100.1.0};
\node at (1.5,1.6) {\ttfamily \vdots};
\pic at (1,2) {cuboid=.9--.9--.5};
\node at (1.45,2.5) {\ttfamily \tiny 2.1.0};
\pic at (1,3) {cuboid=.9--.9--.5};
\node at (1.45,3.5) {\ttfamily \tiny 1.1.0};
\pic at (1,4) {cuboid=.9--.9--.5};
\node at (1.45,4.5) {\ttfamily \tiny 0.1.0};
\node at (2.5,0.5) {\ttfamily \dots};
\node at (2.5,1.55) {\ttfamily $\ddots$};
\node at (2.5,2.5) {\ttfamily \dots};
\node at (2.5,3.5) {\ttfamily \dots};
\node at (2.5,4.5) {\ttfamily \dots};
\pic at (3,0) {cuboid=.9--.9--.5};
\node at (3.45,0.5) {\ttfamily \tiny 100.10.0};
\node at (3.5,1.6) {\ttfamily \vdots};
\pic at (3,2) {cuboid=.9--.9--.5};
\node at (3.45,2.5) {\ttfamily \tiny 2.10.0};
\pic[ultra thick, red] at (3,3) {cuboid=.9--.9--.5};
\node at (3.45,3.5) {\ttfamily \tiny 1.10.0};
\pic at (3,4) {cuboid=.9--.9--.5};
\node at (3.45,4.5) {\ttfamily \tiny 0.10.0};
% front box
\draw[densely dashed] (0,0) -- (3.9,0);
\draw[densely dashed] (0,0) -- (0,4.9);
\draw[densely dashed] (0,4.9) -- (3.9,4.9);
\draw[densely dashed] (3.9,0) -- (3.9,4.9);
%% dimensions
\draw[stealth-stealth] (0.1,-0.2) -- (3.8,-0.2) node[midway,below] {\scriptsize samples};
\draw[stealth-stealth] (4,-0.2, 0) -- (4,-0.2,-.5) node[midway,below right] {\scriptsize ploidy};
\draw[stealth-stealth] (4.1,.1,-.5) -- (4.1,4.8,-.5) node[midway,below,rotate=90] {\scriptsize variants};
%% compresion
\node (numcodecs) [rectangle, draw, densely dotted, thick, rounded corners, minimum width=2.4cm, minimum height=2.6cm, anchor= south west]
at (4.8,2.2) {};
\node[anchor=north,below] at (numcodecs.north) {\scriptsize Filter \& compress};
\node[anchor=south,below] at (numcodecs.south) {numcodecs};
\node (blosk) [rectangle, ultra thick, red, draw, rounded corners, minimum width=1.8cm, minimum height=1.6cm, anchor=center,align=center,text=black]
at (numcodecs) {\scriptsize Blosc\\\scriptsize ZSTD\\\scriptsize Autoshuffle};
\draw[ultra thick, red,-stealth] (3.9,3.5,-.25) -- (5,3.5,-.25);
%% storage
\node (location) [rectangle, draw, densely dotted, thick, rounded corners, minimum width=2.4cm, minimum height=5cm, anchor= south west]
at (7.4,1.1) {};
\node[anchor=south,below] at (location.south) {Storage};
\node[anchor=center] at (location) {
\begin{forest}
for tree={
font=\tiny ,
grow'=0,
child anchor=west,
parent anchor=south,
anchor=west,
calign=first,
edge path={
\noexpand\path [draw, \forestoption{edge}]
(!u.south west) +(7.5pt,0) |- node[fill,inner sep=1.25pt] {} (.child anchor)\forestoption{edge label};
},
before typesetting nodes={
if n=1
{insert before={[,phantom]}}
{}
},
fit=band,
before computing xy={l=15pt},
}
[{\scriptsize Cloud, file or blob}
[\ttfamily call\textunderscore genotype
[\ttfamily 0.0.0]
[\ttfamily ...]
[\ttfamily 1.10.0, draw={red,ultra thick, rounded corners}]
[\ttfamily ...]
[\ttfamily 100.10.0]
]
[\ttfamily sample\textunderscore id]
[\ttfamily ...]
]
\end{forest}
};
\draw[ultra thick, red, -stealth,rounded corners=5pt] (6.8,3.5,-.25) -- (8,3.5,-.25);
\end{tikzpicture}
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment