2

EDIT 2 (Feb 20): New question (hopefully clearer)

With pgfplots it's possible to obtain "inner" and "outer" figure legend (see Paul Gessler's answer) as:

enter image description here

I would like to achieve the same result with a "simple" Tikz picture (i.e. not a plot).

Currently, thanks to this answer or John Kormylo's anwser below, I am able to create a legend with a Tikzpicture positionned with current bounding box.south east (see MWE at the end):

enter image description here

So, positionning with current bounding box.south east is equivalent to the "outer" positionning with pgfplots.

How can I achieve the equivalent to the "inner" positionning with the legend in the previous figure and without using an absolute shift (i.e. [yshift=.., xshift=..]) but using something like pos=inner current bounding box.south east instead?

I specify that the way the legend is built in my MWE is not limiting, that is to say that I am open to other ways of creating a legend (with scope, path,...) if that makes "inner" positioning possible.

EDIT 3 (Feb 24): First attempt

Thanks to Ulrike Fischer comment below, I get this (which is very closed to my needs):

enter image description here

The last problem is a legend overlap with the node. I wonder if I can detect or access to the legend node height in order to plot the legend node with a yshift equal to its height (because the legend could be a multiline matrix).

Thanks to percusse answer here I'm able to obtain this:

enter image description here

Where, the "bleu legend" is the final result I would like to obtain. The "black legend" was used only to determine the legend node height and I would like to delete it... The red text and line show the lenght of the yshit stored in \mytemp and corresponding to the legend node height.

How can I remove the black legend after determining its height?

Or any other idea to automatically set the yshift in order to avoid overlaping?

And the MWE:

\documentclass[tikz=true,crop=true,class=minimal,border=1pt,10pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}
\begin{scope}[local bounding box=localbox]
% NODES
\node (n1)  [draw, text width=5em, minimum height=8em]   {node 1};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-latex]  (aux2b -| n1.east) 
    to (aux2b) node[right] {a bit longer label};
\end{scope}   
% LEGEND
% First black Legend
 \path (localbox.north west)%
 node[name=legend,matrix,anchor=west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };%

% Access to black legend node height
\pgfpointdiff{\pgfpointanchor{legend}{south west}}{\pgfpointanchor{legend}{north west}}
\pgfmathsetmacro\mytemp{\csname pgf@y\endcsname}
\draw[red] ([xshift=1mm]legend.north east) -- ++(0pt,\mytemp pt) 
                                                         node[midway,right] {\mytemp pt};
% Final blue legend                                              
 \path ([yshift=\mytemp pt]localbox.north west)%
  node[name=legend,matrix,anchor=west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex,draw=blue!80]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };% 
\end{tikzpicture}
\end{document}

EDIT 4: Second attempt

Here is my ugly but "working" solution.

  • If there is NO overlapping, the legend is just polted with (using a scope: local bounding box=localbox) \path (localbox.south east) node[name=legend,anchor=west... enter image description here

  • If there is overlapping (the legend is shifted reagarding to it's own size):

  1. First, a temporary legend node is plotted at (0,0) coodinate: enter image description here

  2. Second, the size (widht and height) of this legend is extracted (thanks to percusse answer here).

  3. Third, the temporary legend is entirely hide by a white rectangle: \node (whiterec) [rectangle,fill=white,draw=white,minimum height=\mytemp pt,minimum width=\legendwidth pt] at (legend){};

  4. Fourth, the content of the Tikzpicture is plotted.

  5. Fifth, the final legend is plotted and shifted regarding the size of the remporary legend (here an exemple at north west): enter image description here

The MWE:

\documentclass[tikz=true,crop=true,class=minimal,border=1pt,10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}

\begin{document}
\begin{tikzpicture}
\begin{scope}[local bounding box=localbox]
% First temporary black Legend
 \path (0,0)%
node[name=legend,matrix,anchor=west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };%
% Access to black legend node height and width
\pgfpointdiff{\pgfpointanchor{legend}{south west}}{\pgfpointanchor{legend}{north west}}%
\pgfmathsetmacro\legendheight{\csname pgf@y\endcsname}                                                                                         
\pgfpointdiff{\pgfpointanchor{legend}{west}}{\pgfpointanchor{legend}{east}}%
\pgfmathsetmacro\legendwidth{\csname pgf@x\endcsname}%
% NODES
\node (whiterec) [rectangle,fill=white,draw=white,minimum height=\legendheight pt,minimum width=\legendwidth pt] at (legend){};
\node (n1)  [draw, text width=5em, minimum height=8em]   {node 1};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-latex]  (aux2b -| n1.east) 
    to (aux2b) node[right] {a bit longer label};:
% LEGEND
% Final blue legend                                              
 \path ([yshift=\legendheight/2 pt+1pt]localbox.north west)%
  node[name=legend,matrix,anchor=west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex,draw=blue!80]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };% 
\end{scope}%
\end{tikzpicture}
\end{document}

The question is, is there a way to simplify this method?

For exemple, is it possible to acces the legend size witouht "plotting" it first and after hiding it?

Old question (unclear)

Thanks to this answer I am able to plot a legend like this with a Tikzpicture (the legend is in the bottom right corner in the figure below, placed with \path(current bounding box.south east), see MWE at the end):

enter image description here

But I would prefer this result (warning: red things are not wanted in the final result, it is just for explanation purpose):

enter image description here

Start EDIT 1.1 In other words, I would like to place the legend with something equivalent to (current bounding box.south east) but not starting relatively from the south east of the bounding box but from the south east "inside of the picture borders" instead (green coordinates in the following figure). (BTW I'm not sure the red lines reflect the real behaviour and coordinates when unsing (current bounding box.south east))

enter image description here

End EDIT 1.1

Another exemple of expected result would be, with a bigger node:

enter image description here

Or this (with something like north east):

enter image description here

  • Is there a way to obtain this behaviour automatically by using someting like (current "limits" box.south east)?
  • If yes, it is also possible to choose the minimal vertical distance represented by the ymin in the figure above (which could take negative values): \path([ymin=-5mm]current limits box.south east)?
  • If yes, it is also possible to choose also a minimal horizontal distance xmin like this:

enter image description here

The MWE:

\documentclass[tikz=true,crop=true,class=minimal,border=1pt,10pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}
% NODES
\node (n1)  [draw, text width=5em, minimum height=8em]   {node 1};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-latex]  (aux2b -| n1.east) 
    to (aux2b) node[right] {a bit longer label};
% LEGEND
 \path (current bounding box.south east)%
 node[matrix,anchor=north west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };%
\end{tikzpicture}
\end{document}

Start EDIT 1.2 Why I want that?

Auto-positionning of the legend "inside the image limits" would allow very fast positionning with compact picture by just giving a ymin in order to be sure to not overlap anything with the legend.

This "clever" behaviour would allow the possibility to better automate the picture generation by adding the legend automaticaly and set, for e.g. ymin=1mm and xmin=1mm to prevent any overlaping problem.

End EDIT 1.2

6
  • You can create a [local bounding box=name] with a scope. It will have all the usual anchors. Feb 18 at 14:20
  • @John Thanks. What do you mean by "with a scope"? Feb 18 at 17:58
  • While you don't have to do it this way, I have always used \begin{scope}[local bounding box=name] ... \end{scope} to create named boxes. Feb 18 at 22:15
  • @John Ok, I tried some things but I don't know how to place the scope in the picture. In order to be sure I well understand your comment, your are proposing to use \begin{scope}[local bounding box=name] ... \end{scope} instead of \path (current bounding box.south east)... for the legend "block" only right? Feb 19 at 19:54
  • 1
    it doesn't make sense to think in "inner" and "outer" concepts. Nodes are placed by putting one of their anchors at a certain coordinate. If you want the node to be below and left of (current bounding box.south east) use anchor=north east. Feb 24 at 16:55

3 Answers 3

1

You lost me on the "legend" construction. See Using a pgfplots-style legend in a plain-old tikzpicture for alternatives.

You can also use \begin{scope}[shift=(fred.south east)] ...\end{scope} to position another scope relative to the local bounding box (fred).

\documentclass[tikz=true,crop=true,class=minimal,border=1pt,10pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}
\begin{scope}[local bounding box=fred]
% NODES
\node (n1)  [draw, text width=5em, minimum height=8em]   {node 1};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-latex]  (aux2b -| n1.east) 
    to (aux2b) node[right] {a bit longer label};
\end{scope}
% LEGEND
 \path (fred.south east)%
 node[matrix,anchor=north west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };%
\end{tikzpicture}
\end{document}
3
  • Thank you very much for your answer and comments. I like this way of doing using scopes, thanks for that. Unfortunetly, it gives exactly the same results as in my MWE... Feb 20 at 11:55
  • 1
    So basically you wan to apply a shift? With the calc tikzlibrary one can use ($(fred.south east) + (xshift,yshift)$). Or you could define a new location using \path (fred.south east) ++ (xshift,yshift) coordinate (wilma); Feb 20 at 15:31
  • Ok my question is still unclear sorry. I made a second edit... Feb 20 at 20:27
0

I am not really sure what you try to do. Maybe the following can be of use!?

\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\newcommand{\ymin}{-5mm}
\newcommand{\xmin}{0mm}
% NODES
\node (n1)  [draw, text width=5em, minimum height=8em]   {node 1};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-latex]  (aux2b -| n1.east) 
    to (aux2b) node[right, inner sep=0] (n) {a bit longer label};
% LEGEND
 \path ([yshift=\ymin, xshift=\xmin]current bounding box.south east)%
 node[matrix,anchor=north west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };%
 \draw[red, dashed] (n.south east) -- +(0,3)  -- +(0,-2);
\draw[red, dashed] (n1.south west) -| (n.south east);
\end{tikzpicture}
\end{document}

Rectangle node with arrows

1
  • Thanks for your answer. This solution was already proposed in the linked answer and here I would like something more clever... It make me realise that my question was unclear. Indeed, I wonder if it could be possible to have an equivalent to ([yshift=\ymin, xshift=\xmin]current bounding box.south east) but NOT starting from the south east of the bouding box but from the south east of the "picture borders" (see EDIT 1.1 and 1.2 of my question for more details). Thanks again anyway! Feb 18 at 6:26
0

This answer is here in order to not let this question without an accepted "working" answer, if someone (by the greatest of chance) comes across this solution and wishes (strangely) to use it.
So, if someone wants to improve it or gives another solution, I'll accept that answer if any.

Here is the ugly solution I finally used, presented in two ways: manual method and method using a new environment.

Both methods use the legend anchor to achieve the right "inner" positioning (thanks to Ulrike Fischer's comment).

Manual solution

  • If there is NO overlapping, the legend is just polted with (using a scope: local bounding box=localbox) \path (localbox.south east) node[name=legend,anchor=west... enter image description here

  • If there is overlapping (the legend is shifted reagarding to it's own size):

  1. First, a temporary legend node is plotted at (0,0) coodinate: enter image description here

  2. Second, the size (widht and height) of this legend is extracted (thanks to percusse's answer here).

  3. Third, the temporary legend is entirely hide by a white rectangle: \node (whiterec) [rectangle,fill=white,draw=white,minimum height=\legendheight pt,minimum width=\legendwidth pt] at (legend){};

  4. Fourth, the content of the Tikzpicture is plotted.

  5. Fifth, the final legend is plotted and shifted regarding the size of the remporary legend (here an exemple at north west): enter image description here

The MWE:

\documentclass[tikz=true,crop=true,class=minimal,border=1pt,10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}

\begin{document}
\begin{tikzpicture}
\begin{scope}[local bounding box=localbox]
% First temporary black Legend
 \path (0,0)%
node[name=legend,matrix,anchor=west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };%
% Access to black legend node height and width
\pgfpointdiff{\pgfpointanchor{legend}{south west}}{\pgfpointanchor{legend}{north west}}%
\pgfmathsetmacro\legendheight{\csname pgf@y\endcsname}                                                                                         
\pgfpointdiff{\pgfpointanchor{legend}{west}}{\pgfpointanchor{legend}{east}}%
\pgfmathsetmacro\legendwidth{\csname pgf@x\endcsname}%
% NODES
\node (whiterec) [rectangle,fill=white,draw=white,minimum height=\legendheight pt,minimum width=\legendwidth pt] at (legend){};
\node (n1)  [draw, text width=5em, minimum height=8em]   {node 1};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-latex]  (aux2b -| n1.east) 
    to (aux2b) node[right] {a bit longer label};:
% LEGEND
% Final blue legend                                              
 \path ([yshift=\legendheight/2 pt+1pt]localbox.north west)%
  node[name=legend,matrix,anchor=west,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex,draw=blue!80]{%
  \draw[-latex](0,0) -- ++ (0.6,0); & \node{arrow};\\
 };% 
\end{scope}%
\end{tikzpicture}
\end{document}

Method using a new environment

This method uses a new tikzpictureWithInnerLegend environment wich act as a tikzpicture environment but automaticaly draw the temporary legend, get its size and plot the final legend (in the same way as the Manual Method above).

  1. First the style of the Final an temporary legends are defined, e.g.:
\tikzstyle{legend}=[name=legend,matrix,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex,draw=blue!80]%
\tikzstyle{templegend}=[name=templegend,matrix,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex,draw=white,fill=white]%
  1. The legend content is stored into a macro, e.g.:
\newcommand{\legendcontent}{%
\draw[-latex](0,0) -- ++ (0.6,0); \& \node{arrow};\\% Be carefful to put \& instead of &
\draw[-stealth](0,0) -- ++ (0.6,0); \& \node{arrow2};\\% Be carefful to put \& instead of &
}%
  1. The enviroment is called, e.g. with a lengend at current bounding box.south east:
\begin{tikzpictureWithInnerLegend}{\legendcontent}{current bounding box.south east}[xshift=\xmin, yshift=\ymin, autoshiftsign=true]
% NODES
\node (n1)  [draw, text width=5em, minimum height=8em]  {node};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-stealth]  (aux2b -| n1.east) 
    to (aux2b) node[right] {a bit longer label};:
\end{tikzpictureWithInnerLegend}

enter image description here

  1. The environment options are as follows:
  • [xshift=\xmin, yshift=\ymin]: apply respectively a xshift and a yshift to the final legend positioning.
  • [autoshiftsign=true]: automatically change the sign of the xshift and yshift in order to avoid legend overlapping. Default value is false even if you just write [autoshiftsign] (i.e. the signs are directly given with the xshift and yshift options, e.g.: xshift=-3pt).

Limitations and possible improvements

  1. The code could be greatly improved in order to be more readable and efficient, e.g. many things are written identically in several places (in the start environment code with or without optional argument for example), as is the case with the \pgfkeys macro.
  2. The use of listofitems package could probably be avoided. This package is only used in order to split the legend location given by the user, e.g. in current bounding box.south east the key east is extracted in oder to set the legend anchor. Also, it permits to make the difference between current bounding box.south east and current bounding box.south.

Whole (ugly) code:

\documentclass[tikz=true,crop=true,class=minimal,border=1pt,10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,calc,matrix}
\usepackage{listofitems}
\usepackage{xparse}


\NewDocumentEnvironment{tikzpictureWithInnerLegend}{m m o}%
{\IfNoValueTF{#3}{%
% # Start code if no opt arg
%-----------------------------------------------------------
% ## Initialization
\pgfkeys{
 /tikzpictureWithInnerLegend/.is family, /tikzpictureWithInnerLegend/.cd, %<-added /.cd 
 autoshiftsign/.is choice,
 autoshiftsign/.default=false,
 autoshiftsign/true/.code={\renewcommand{\autoShiftSignBool}{1}},
 autoshiftsign/false/.code={\renewcommand{\autoShiftSignBool}{0}},
 xshift/.estore in ={\xShift},
 yshift/.estore in ={\yShift},
} 
\newcommand*{\pathLocation}{}
\newcommand*{\lgdAnchor}{}
\newcommand{\xshiftSign}{0}
\newcommand{\yshiftSign}{0}
\newcommand{\xShift}{0}
\newcommand{\yShift}{0}
\newcommand{\xAutoShiftBool}{0}
\newcommand{\yAutoShiftBool}{0}
\newcommand{\autoShiftSignBool}{0}
\def\zero{0}%
\def\plus{+}%
\def\minus{-}%
\def\north{north}%
\def\south{south}%
\def\east{east}%
\def\west{west}%
% ## Main Start Code
\ignoreemptyitems% Ingnore empty items from the list
\setsepchar{.}%
\readlist\mylist{#2}%
\setsepchar{ }%
\itemtomacro\mylist[2]\mylistmacro
\readlist\mysublist{\mylistmacro}%
\itemtomacro\mysublist[1]\cardinal
\if\mysublistlen2
  \renewcommand*{\pathLocation}{\mylist[1].\mysublist[1] \mysublist[2]}%
  \renewcommand*{\lgdAnchor}{\mysublist[2]}%
    \ifx\north\cardinal
        \renewcommand{\yshiftSign}{+}%
        \renewcommand{\yAutoShiftBool}{1}%
    \else 
            \ifx\south\cardinal
            \renewcommand{\yshiftSign}{-}%
            \renewcommand{\yAutoShiftBool}{1}%
         \else
            \renewcommand{\yshiftSign}{+}%
            \renewcommand{\yAutoShiftBool}{0}%
            \ifx\east\cardinal
                    \renewcommand{\xshiftSign}{+}%
                    \renewcommand{\xAutoShiftBool}{1}%
            \else
                    \renewcommand{\xshiftSign}{-}%
                    \renewcommand{\xAutoShiftBool}{1}%   
             \fi
         \fi
   \fi
\else
  \renewcommand*{\pathLocation}{\mylist[1].\mysublist[1]}%
  \renewcommand*{\lgdAnchor}{\mysublist[1]}%
    \ifx\north\cardinal
        \renewcommand{\yshiftSign}{+}%
        \renewcommand{\yAutoShiftBool}{1}%
        \renewcommand*{\lgdAnchor}{center}%
    \else 
            \ifx\south\cardinal
            \renewcommand{\yshiftSign}{-}%
            \renewcommand{\yAutoShiftBool}{1}%
            \renewcommand*{\lgdAnchor}{center}%
         \else
            \renewcommand{\yshiftSign}{+}%
            \renewcommand{\yAutoShiftBool}{0}%
            \ifx\east\cardinal
                    \renewcommand{\xshiftSign}{+}%
                    \renewcommand{\xAutoShiftBool}{1}%
            \else
                    \renewcommand{\xshiftSign}{-}%
                    \renewcommand{\xAutoShiftBool}{1}%    
             \fi
         \fi
   \fi
\fi
\begin{tikzpicture} [ampersand replacement=\&]
% ### Print temporary legend node
 \path (0,0)%
node[templegend]{#1};%
% ### Access to temporary legend node height and width
\pgfpointdiff{\pgfpointanchor{templegend}{south west}}{\pgfpointanchor{templegend}{north west}}%
\pgfmathsetmacro\legendheight{\csname pgf@y\endcsname}                                                                                         
\pgfpointdiff{\pgfpointanchor{templegend}{west}}{\pgfpointanchor{templegend}{east}}%
\pgfmathsetmacro\legendwidth{\csname pgf@x\endcsname}%
\node (whiterec) [rectangle,fill=white,draw=white,minimum height=\legendheight pt,minimum width=\legendwidth pt] at (templegend){};
}%
{%
% # Start code if opt arg
%-----------------------------------------------------------
% ## Initialization
\pgfkeys{
 /tikzpictureWithInnerLegend/.is family, /tikzpictureWithInnerLegend/.cd, %<-added /.cd 
 autoshiftsign/.is choice,
 autoshiftsign/.default=false,
 autoshiftsign/true/.code={\renewcommand{\autoShiftSignBool}{1}},
 autoshiftsign/false/.code={\renewcommand{\autoShiftSignBool}{0}},
 xshift/.estore in ={\xShift},
 yshift/.estore in ={\yShift},
} 
\newcommand*{\pathLocation}{}
\newcommand*{\lgdAnchor}{}
\newcommand{\xshiftSign}{0}
\newcommand{\yshiftSign}{0}
\newcommand{\xShift}{0}
\newcommand{\yShift}{0}
\newcommand{\xAutoShiftBool}{0}
\newcommand{\yAutoShiftBool}{0}
\newcommand{\autoShiftSignBool}{0}
\def\zero{0}%
\def\plus{+}%
\def\minus{-}%
\def\north{north}%
\def\south{south}%
\def\east{east}%
\def\west{west}%
% ## Main Start Code
\pgfkeys{/tikzpictureWithInnerLegend,#3}%
\ifx\minus\xshiftSign
    \renewcommand{\xAutoShiftBool}{1}%
\else
    \ifx\plus\xshiftSign
            \renewcommand{\xAutoShiftBool}{1}%
    \else
    \renewcommand{\xAutoShiftBool}{0}%
    \fi
\fi
\ifx\minus\yshiftSign
    \renewcommand{\yAutoShiftBool}{1}%
\else
    \ifx\plus\yshiftSign
            \renewcommand{\yAutoShiftBool}{1}%
    \else
    \renewcommand{\yAutoShiftBool}{0}%
    \fi
\fi
\ignoreemptyitems% Ingnore empty items from the list
\setsepchar{.}%
\readlist\mylist{#2}%
\setsepchar{ }%
\itemtomacro\mylist[2]\mylistmacro
\readlist\mysublist{\mylistmacro}%
\itemtomacro\mysublist[1]\cardinal
\if\mysublistlen2
  \renewcommand*{\pathLocation}{\mylist[1].\mysublist[1] \mysublist[2]}%
  \renewcommand*{\lgdAnchor}{\mysublist[2]}%
    \ifx\north\cardinal
        \renewcommand{\yshiftSign}{+}%
        \renewcommand{\yAutoShiftBool}{1}%
    \else 
            \ifx\south\cardinal
            \renewcommand{\yshiftSign}{-}%
            \renewcommand{\yAutoShiftBool}{1}%
         \else
            \renewcommand{\yshiftSign}{+}%
            \renewcommand{\yAutoShiftBool}{0}%
            \ifx\east\cardinal
                    \renewcommand{\xshiftSign}{+}%
                    \renewcommand{\xAutoShiftBool}{1}%
            \else           
                    \renewcommand{\xshiftSign}{-}%
                    \renewcommand{\xAutoShiftBool}{1}%
             \fi
         \fi
\fi
\else
  \renewcommand*{\pathLocation}{\mylist[1].\mysublist[1]}%
  \renewcommand*{\lgdAnchor}{\mysublist[1]}%
    \ifx\north\cardinal
        \renewcommand{\yshiftSign}{+}%
        \renewcommand{\yAutoShiftBool}{1}%
        \renewcommand*{\lgdAnchor}{center}%
    \else 
            \ifx\south\cardinal
            \renewcommand{\yshiftSign}{-}%
            \renewcommand{\yAutoShiftBool}{1}%
            \renewcommand*{\lgdAnchor}{center}%
         \else
            \renewcommand{\yshiftSign}{+}%
            \renewcommand{\yAutoShiftBool}{0}%
            \ifx\east\cardinal
                    \renewcommand{\xshiftSign}{+}%
                    \renewcommand{\xAutoShiftBool}{1}%
            \else
                    \ifx\west\cardinal
                        \renewcommand{\xshiftSign}{-}%
                        \renewcommand{\xAutoShiftBool}{1}%
                \else% Center
                        \renewcommand{\xshiftSign}{+}%
                        \renewcommand{\yshiftSign}{+}%
                        \renewcommand{\xAutoShiftBool}{0}%  
                        \renewcommand{\yAutoShiftBool}{0}% 
                        \renewcommand*{\lgdAnchor}{center}%
                \fi     
             \fi
         \fi
\fi
\fi
\begin{tikzpicture} [ampersand replacement=\&]%
% ### Print temporary legend node
 \path (0,0)%
node[templegend]{#1};%
% ### Access to temporary legend node height and width
\pgfpointdiff{\pgfpointanchor{templegend}{south west}}{\pgfpointanchor{templegend}{north west}}%
\pgfmathsetmacro\legendheight{\csname pgf@y\endcsname}%                                                                                         
\pgfpointdiff{\pgfpointanchor{templegend}{west}}{\pgfpointanchor{templegend}{east}}%
\pgfmathsetmacro\legendwidth{\csname pgf@x\endcsname}%
\node (whiterec) [rectangle,fill=white,draw=white,minimum height=\legendheight pt,minimum width=\legendwidth pt] at (templegend){};%
}}%
{\IfNoValueTF{#3}{%
% # End code if no opt arg
%-----------------------------------------------------------
% ## LEGEND                                             
\path ([xshift=\xAutoShiftBool*\legendwidth*\xshiftSign1 pt+\autoShiftSignBool*\xShift*\xshiftSign1+(1-\autoShiftSignBool)*\xShift,yshift=\yAutoShiftBool*\legendheight/2*\yshiftSign1 pt+\autoShiftSignBool*\yShift*\yshiftSign1+(1-\autoShiftSignBool)*\yShift]#2)%
node[legend,anchor=\lgdAnchor]{#1};%
    \end{tikzpicture}%
}%
{%
% # End code if opt arg
%-----------------------------------------------------------
% ## LEGEND                                             
\path ([xshift=\xAutoShiftBool*\legendwidth*\xshiftSign1 pt+\autoShiftSignBool*\xShift*\xshiftSign1+(1-\autoShiftSignBool)*\xShift,yshift=\yAutoShiftBool*\legendheight/2*\yshiftSign1 pt+\autoShiftSignBool*\yShift*\yshiftSign1+(1-\autoShiftSignBool)*\yShift]#2)%
node[legend,anchor=\lgdAnchor]{#1};%
    \end{tikzpicture}%
}}%



\begin{document}
% Legend Formating
\tikzstyle{legend}=[name=legend,matrix,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex,draw=blue!80]%
\tikzstyle{templegend}=[name=templegend,matrix,cells={nodes={font=\sffamily,anchor=west}},
 draw,thick,inner sep=0.3ex,draw=white,fill=white]%
% Legend Content
\newcommand{\legendcontent}{%
\draw[-latex](0,0) -- ++ (0.6,0); \& \node{arrow};\\% Be carefful to put \& instead of &
\draw[-stealth](0,0) -- ++ (0.6,0); \& \node{arrow2};\\% Be carefful to put \& instead of &
}%
% Legend manual shift
\newcommand{\xmin}{0pt}% Minimal xshift to avoid ovelapping
\newcommand{\ymin}{1pt}% Minimal yshift to avoid ovelapping

\begin{tikzpictureWithInnerLegend}{\legendcontent}{current bounding box.south east}[xshift=\xmin, yshift=\ymin, autoshiftsign=true]
% NODES
\node (n1)  [draw, text width=5em, minimum height=8em]  {node};%
% ARROWS
\coordinate[above right=of n1.east] (aux2a);
\coordinate[below right=of n1.east] (aux2b);
%
\draw[-latex]  (aux2a -| n1.east) 
    to (aux2a) node[right] {short label};
\draw[-stealth]  (aux2b -| n1.east) 
    to (aux2b) node[right] {a bit longer label};:
\end{tikzpictureWithInnerLegend}

\end{document}

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.