2

I have generated the graphic below with the following code:

\documentclass[11pt]{article} 
\usepackage{tikz,xifthen}
\usetikzlibrary{arrows, decorations.text, decorations.markings, shapes, patterns, positioning, shapes.multipart, fit}




\begin{document}
\thispagestyle{empty} %Please, no page numbers or similar


\begin{figure}[Htbp]
\centering


\begin{tikzpicture}[scale=3]

\def\trainingSamples{0.17/0.76/2,  0.14/0.62/2,  0.23/0.63/2,  0.25/0.77/2,  0.11/0.68/2,  0.25/0.68/2,  0.16/0.68/2,  0.72/0.55/1,  0.68/0.46/1,  0.74/0.39/1,  0.82/0.53/1,  0.75/0.64/1,  0.81/0.40/1,  0.46/0.28/3,  0.33/0.28/3,  0.22/0.17/3,  0.22/0.24/3,  0.28/0.10/3,  0.31/0.19/3,  0.51/0.16/3,  0.37/0.12/3,  0.42/0.20/3,  0.49/0.24/3,  0.19/0.54/2,  0.31/0.58/2,  0.41/0.67/2,  0.35/0.75/2,  0.32/0.67/2,  0.28/0.85/2,  0.67/0.55/1,  0.70/0.63/1,  0.78/0.54/1,  0.66/0.36/1,  0.63/0.21/3,  0.70/0.29/1,  0.74/0.21/1,  0.62/0.46/1,  0.40/0.27/3,  0.39/0.17/3,  0.32/0.24/3}
\def\testSamples{0.14/0.71,  0.24/0.79,  0.23/0.60,  0.13/0.61,  0.11/0.49,  0.38/0.69,  0.27/0.71,  0.16/0.86,  0.06/0.67,  0.17/0.54,  0.33/0.79,  0.36/0.55,  0.92/0.65,  0.81/0.47,  0.30/0.28,  0.19/0.18,  0.40/0.12,  0.52/0.23,  0.23/0.10,  0.37/0.27 }

\def\blockSpace{.2}

\tikzset{Marker/.style={inner sep=0pt,minimum size=3pt}}
\tikzset{classMarker/.style={regular polygon,regular polygon sides=3,Marker,minimum size=4pt}}
\tikzset{trainingMarker/.style={fill,circle,Marker}}
\tikzset{testMarker/.style={fill,regular polygon,regular polygon sides=4,Marker,minimum size=4pt,teal}}
\tikzset{classAMarker/.style={rotate=0,classMarker,red}}
\tikzset{classBMarker/.style={rotate=-90,classMarker,violet}}
\tikzset{classCMarker/.style={rotate=180,classMarker,blue}}
\tikzset{textNode/.style={anchor=north,text width=3cm, align=center}}
\tikzset{lineTextNode/.style={bend left,anchor=south,text width=4cm, align=center}}


%\draw [help lines,step=.2] (-.5,-.5) grid (5,1.5);
%\draw [step=1] (-.5,-.5) grid (5,1.5);

\foreach \x/\y/\classID in \trainingSamples
 \draw (\x,\y) node[trainingMarker]{};

\foreach \x/\y/\classID in \trainingSamples {
    \ifthenelse{\classID = 1}
        { \draw (1+\blockSpace+\x,\y) node[fill,classAMarker]{};}
        {\ifthenelse{\classID = 2}
            { \draw (1+\blockSpace+\x,\y) node[fill,classBMarker]{};}
            { \draw (1+\blockSpace+\x,\y) node[fill,classCMarker]{};}
        }
}

\foreach \x/\y in \testSamples
 \draw (2+2*\blockSpace+\x,\y) node[testMarker]{};

\draw   (1+\blockSpace+.7225,.4612) node[draw,classAMarker,fill=white]{}
            (1+\blockSpace+.2436,.6823) node[draw,classBMarker,fill=white]{}
            (1+\blockSpace+.3818,.2057) node[draw,classCMarker,fill=white]{};

\draw   (2+2*\blockSpace+.7225,.4612) node[draw,classAMarker,fill=white]{}
            (2+2*\blockSpace+.2436,.6823) node[draw,classBMarker,fill=white]{}
            (2+2*\blockSpace+.3818,.2057) node[draw,classCMarker,fill=white]{};

\begin{scriptsize}
\draw   (.5,0)  node[textNode]{Local features of training images}
            (1.5+\blockSpace,0) node[textNode]{Clustered training \\ features}
            (2.5+2*\blockSpace,0) node[textNode]{Local features of testing images }
            (3.5+3*\blockSpace,0) node[textNode]{Normalized Bag-of-Features (BoF) }
            ;

\path[->,>=stealth',shorten >=1pt,auto,node distance=2.8cm,
                    semithick] 
                    (.9,.85) edge [lineTextNode]    node{Generate the dicctionary} +(.2+\blockSpace,0)
                    (1.9+\blockSpace,.85) edge [lineTextNode]   node{Keyword assignation} +(.2+\blockSpace,0)
                    (2.9+2*\blockSpace,.85) edge [lineTextNode] node{Feature generation} +(.2+\blockSpace,0)
                    ;
\end{scriptsize}

\draw (3.1+4*\blockSpace,.3) node[] (HistOrigin){};

\draw[->,>=stealth',shorten >=1pt,auto] (HistOrigin) +(-0.05,0) -- ++(-0.05,.6);

\draw[-|,shorten >=1pt,auto] (HistOrigin)  +(-0.05,0) -- +(-0.05,.48);
\draw[-o,shorten >=1pt,auto] (HistOrigin)  +(.1,0) --    +(.1,.5);
\draw[-|,shorten >=1pt,auto] (HistOrigin)  +(-0.05,0) -- +(-0.05,.08);
\draw[-o,shorten >=1pt,auto] (HistOrigin)  +(.3,0) --    +(.3,.1);
\draw[-|,shorten >=1pt,auto] (HistOrigin)  +(-0.05,0) -- +(-0.05,.24);
\draw[-o,shorten >=1pt,auto] (HistOrigin)  +(.5,0) --  +(.5,.26);


\begin{tiny}
\draw (HistOrigin) ++ (.1,-.045) node [draw,classAMarker,fill=white,anchor=center]{}
            (HistOrigin) ++(.325,-.04) node [draw,classBMarker,fill=white,anchor=north]{}
            (HistOrigin) ++(.5,-.065) node [draw,classCMarker,fill=white,anchor=north]{}
            (HistOrigin) ++(-0.1,.08) node [anchor=east,inner sep=0pt]{$2$}
            (HistOrigin) ++(-0.1,.24) node [anchor=east,inner sep=0pt]{$6$}
            (HistOrigin) ++(-0.1,.48) node [anchor=east,inner sep=0pt]{$12$}
            (HistOrigin) ++(0,.55) node [anchor=south west,inner sep=0pt] (histName){word  occurrences}         
            ;
\draw[] (HistOrigin) +(-0.05,0)  --(HistOrigin -| histName.east);           

\draw   (3+3*\blockSpace,.08)   node[ anchor=south west, align=center] (A) {Final feature}  
            node [draw,right=10pt of A,inner sep=0pt,minimum size=10pt] (B) {$.6$}
            node [draw,right=-.5pt of B ,inner sep=0pt,minimum size=10pt] (C) {$.1$}
            node [draw,right=-.5pt of C ,inner sep=0pt,minimum size=10pt] (D) {$.3$}
            ;

\end{tiny}
\end{tikzpicture}

\center
\begin{tikzpicture}
\tikzset{Marker/.style={inner sep=0pt,minimum size=3pt}}
\tikzset{classMarker/.style={regular polygon,regular polygon sides=3,Marker,minimum size=4pt,anchor=center,fill}}
\tikzset{trainingMarker/.style={fill,circle,Marker}}
\tikzset{testMarker/.style={fill,regular polygon,regular polygon sides=4,Marker,minimum size=4pt,teal}}
\tikzset{classAMarker/.style={rotate=0,classMarker,red}}
\tikzset{classBMarker/.style={rotate=-90,classMarker,violet}}
\tikzset{classCMarker/.style={rotate=180,classMarker,blue}}
\tikzset{textNode/.style={anchor=west}}

\def\spaceDist{10pt}
\def\spaceTokenDist{3pt}
\begin{tiny}
\draw   node [ trainingMarker ] (A) {}  
            node [right=\spaceTokenDist of A,textNode] (An) {Training local feature}
            node [right= \spaceDist of An, classAMarker ] (B) {}    
            node [right=\spaceTokenDist of B,textNode] (Bn) {Class A}
            node [right=\spaceDist of Bn, classBMarker ] (C) {} 
            node [right=\spaceTokenDist of C,textNode] (Cn) {Class B}
            node [right=\spaceDist of Cn, classCMarker ] (D) {} 
            node [right=\spaceTokenDist of D,textNode] (Dn) {Class C}
            node [right=\spaceDist of Dn, testMarker ] (E) {}   
            node [right=\spaceTokenDist of E,textNode] (En) {Testing local feature}
            node[draw,fit=(A) (En)]{}
            ;
\end{tiny}          

\end{tikzpicture}
\end{figure}
\end{document}

The problem is that the token used for the different classes are colored rotated triangles, and even rotating them from the center anchor, while generating the legend they do not get vertically aligned when using positioning. On the top of that I did not manage to horizontally align the legend with the figure center. My best attempt has been using another tikzpicture environment. But still the result look shifted still.

enter image description here

I tried also to use the legend environment such as in here but I could not figure out how to pass the tokens I am using.

Sik
  • 1,331
  • If you find any suggestion for the code generating the figure do not hesitate to let me know I am sure there are million ways faster to code such figure, because to my understanding it took me to much to code it. – Sik Oct 30 '13 at 16:29
  • I have started working with this code several times, and each time I am overwhelmed. You might get more attention if you edited this post to contain one specific question and a simple code illustrating your best attempt so far. :-) – Paul Gessler Mar 30 '14 at 23:31
  • No worries the figure was good enough for what I needed. But I guess that with the post I was looking for a second opinion or new hints that let me to a better figures coding path. But I guess that this kind of question is a) difficult to post, sine MWE are so reduced that don't have such code structuring problems. b) difficult to came across while reading posts. – Sik Mar 31 '14 at 08:55
  • Thanks for the update Sik. What should the status of this question be then? I don't think code reviews are quite suited to our format, but if you've solved it on your own, a self-answer would be helpful for any future visitors. – Paul Gessler Mar 31 '14 at 16:33
  • dropped? I never could figure it out. I struggle through it, found couple possible leads. But I had to drop it and let the legend with all this misalignment due to time constrains. At the end no body complained. – Sik Apr 02 '14 at 14:37

1 Answers1

1

A quick demo of pgfplots capabilities though you can do much more. The most important part is how you can easily reuse the data (which massaged a little to get rid of commas and replace them with \\)

\documentclass[11pt]{article} 
\usepackage{pgfplots}
\pgfplotsset{every crossref picture/.style={baseline={([yshift=-0.5ex]current bounding box.center)}}}
\usetikzlibrary{plotmarks}
\pgfplotsset{compat=1.10}
\pgfplotstableread[row sep=\\,white space chars={/},format=inline]{0.17/0.76/2\\ 0.14/0.62/2\\ 0.23/0.63/2\\ 0.25/0.77/2\\ 0.11/0.68/2\\ 0.25/0.68/2\\ 0.16/0.68/2\\ 0.72/0.55/1\\ 0.68/0.46/1\\ 0.74/0.39/1\\ 0.82/0.53/1\\ 0.75/0.64/1\\ 0.81/0.40/1\\ 0.46/0.28/3\\ 0.33/0.28/3\\ 0.22/0.17/3\\ 0.22/0.24/3\\ 0.28/0.10/3\\ 0.31/0.19/3\\ 0.51/0.16/3\\ 0.37/0.12/3\\ 0.42/0.20/3\\ 0.49/0.24/3\\ 0.19/0.54/2\\ 0.31/0.58/2\\ 0.41/0.67/2\\ 0.35/0.75/2\\ 0.32/0.67/2\\ 0.28/0.85/2\\ 0.67/0.55/1\\ 0.70/0.63/1\\ 0.78/0.54/1\\ 0.66/0.36/1\\ 0.63/0.21/3\\ 0.70/0.29/1\\ 0.74/0.21/1\\ 0.62/0.46/1\\ 0.40/0.27/3\\ 0.39/0.17/3\\ 0.32/0.24/3\\}\mytable

\begin{document}
\begin{tikzpicture}[scale=0.5]
    \begin{axis}[hide axis,name=plot1,legend to name=lega]
        \addplot[only marks] table[x index=0,y index=1]{\mytable};
        \label{leg:lega}
    \end{axis}

    \begin{axis}[name=plot2,at={(plot1.east)},
                 anchor=west,
                 hide axis,
                 scatter/classes={%
                1={mark=triangle*,red},%
                2={mark=triangle*,rotate=-90,violet},%
                3={,rotate=180,mark=triangle*,blue}},
                ]
        \addplot[scatter,only marks,scatter src=explicit] 
                 table[x index=0,y index=1,meta index=2]{\mytable};
        \label[1]{leg:leg1}
        \label[2]{leg:leg2}
        \label[3]{leg:leg3}
    \end{axis}

    \begin{axis}[at={(plot2.east)},
                 anchor=west,
                 hide axis,
                 scatter/classes={%
                1={opacity=0},%
                2={mark=square*,violet},%
                3={mark=square*,blue}}
                ]
        \addplot[scatter,only marks,scatter src=explicit] table[x index=0,y index=1,meta index=2]{\mytable};
    \end{axis}
\end{tikzpicture}\\

We started training with \ref{leg:lega} and then we got bored and put them next to each other
\ref{leg:leg1} and 
\ref{leg:leg2} and 
\ref{leg:leg3} and 


\end{document}

enter image description here

percusse
  • 157,807