Hallo, ich setze ein TikZ-Bild und ein Listing in einer Figure mittels subfloat-Befehl des subfig Packages. Nun ist das Listing von der Höhe her größer und ich bekomme es einfach nicht hin, das TikZ-Bild daneben vertikal zu zentrieren. Allerdings sollen dabei die Sub-Captions auf derselben Höhe gesetzt sein. Könnt ihr mir da weiterhelfen?

Hier mein Minimalbeispiel:

Open in writeLaTeX
\documentclass{scrartcl}

\usepackage{listings}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage{subfig}
\usepackage{filecontents}

\lstset{numbers=none,frame=none,backgroundcolor=,basicstyle=\ttfamily    \footnotesize,captionpos=b,escapeinside=    {@}{@},aboveskip=7pt,abovecaptionskip=3pt,belowskip=3pt,boxpos=c,showspaces=false,showtabs=false,tabsize=4,breaklines=true,columns=flexible,mathescape}
% RoleModel
\lstdefinelanguage{Roles} 
{keywords={RoleModel, ROLE},keywords=[2]{input, super, transitive, reflexive,     optional},morestring=[s]{[}{]}} 
\lstdefinestyle{Roles} {language=Roles,keywordstyle=\color{role}\bfseries,keywordstyle=    [2]\color{roleKeyword}}

\usetikzlibrary{positioning}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{shapes}
\usetikzlibrary{graphs}
\usetikzlibrary{quotes}

\begin{document}

\definecolor{role}{cmyk}{1.0, 0.417, 0.0, 0.247}
\definecolor{roleKeyword}{cmyk}{0.3, 0.7, 0.0, 0.373}

\tikzset{
    role/.style = {rounded rectangle, minimum size=6mm, very thick, draw=role, top     color=white,bottom color=role!20, font=\sffamily\scriptsize,align=center,text=black},
    skip loop/.style = {to path={-- ++(0,#1) -| (\tikztotarget)}},
    hv/.style = {to path={-| (\tikztotarget) \tikztonodes}},
    vh/.style = {to path={|- (\tikztotarget) \tikztonodes}},
    comp/.style = {Diamond-},
    ass/.style = {-{Straight Barb[angle'=45,round]}},
    imp/.style = {-{Triangle[open,length=7pt]}},
    proh/.style = {{Bar[sep=1pt]}-{Bar[sep=1pt]}}
}

\begin{filecontents*}{repres.role}
RoleModel ExtractX { 
  ROLE OrigContainer; 
  input ROLE Extractee; 
  ROLE NewContainer (newName); 
  ROLE ContainerContainer; 
  transitive : OrigContainer [1..1] 
    <>- Extractee extracts [0..*]; 
  transitive : NewContainer [1..1] 
    <>- Extractee moved [0..*]; 
  transitive : ContainerContainer [1..1] 
    <>- NewContainer target [1..1]; 
  transitive : ContainerContainer [1..1] 
    <>- OrigContainer source [1..*]; 
  transitive : OrigContainer [1..*] 
    -- NewContainer reference [1..*];   
}
\end{filecontents*}

\begin{figure}
    \centering
    \subfloat[Graphical representation.]{
        \label{subfig:RolesGraph}
        \begin{tikzpicture}[node distance=9mm and 0mm,thick,black!50,every edge/.style=    {rounded corners,draw=black!50,text=black,font=\sffamily\scriptsize,near end}]
            \node[role] (ContainerContainer) {ContainerContainer};
            \node[role] (OriginalContainer) [below left=of ContainerContainer]     {OriginalContainer};
            \node[role] (NewContainer) [below right=of ContainerContainer] {NewContainer};
            \node[role] (Extractee) [below right=of OriginalContainer,xshift=15pt]     {Extractee};
            \path
                (ContainerContainer) edge[comp,hv,"target"] (NewContainer)
                (ContainerContainer) edge[comp,hv,"source"] (OriginalContainer)
                (NewContainer) edge[comp,vh,"moved"] (Extractee)
                (OriginalContainer) edge[ass] node[above,xshift=-5pt] {reference}     (NewContainer)
                (OriginalContainer) edge[comp,vh] node[below] {extracts}     (Extractee);

        \end{tikzpicture}
    }
    \qquad  
    \subfloat[Textual representation.]{
        \label{subfig:RolesText}
        \parbox{0.45\textwidth}    {\lstinputlisting[style=Roles,numbers=none,frame=none,backgroundcolor=,basicstyle=\ttfamily    \footnotesize]{repres.role}}
    }
    \caption{Different representations.}
    \label{fig:representations}
\end{figure}

\end{document}

gefragt 26 Mai '14, 17:20

ErnstZ's gravatar image

ErnstZ
611132833
Akzeptiert-Rate: 62%

Willkommen auf der TeXwelt!

(26 Mai '14, 19:45) cgnieder

Für den Fall, dass es unbedingt subfig sein muss, ist hier noch eine Alternative. Dabei wird Teilabbildung mit der größeren Höhe, in dem Fall also das Listing, in einer Box gespeichert. Die niedrigere Teilabbildung wird dann in einer vertikal zentrierten varwidth oder minipage Umgebung mit gleicher Gesamthöhe (= Höhe + Tiefe der abgespeicherten Box) gesetzt.

Open in writeLaTeX
\documentclass{scrartcl}
\usepackage{listings}
\usepackage{tikz}
\usepackage{subfig}
\usepackage{varwidth}

\lstset{numbers=none,frame=none,backgroundcolor=,
  basicstyle=\ttfamily\footnotesize, captionpos=b,escapeinside={@}{@},
  aboveskip=7pt,abovecaptionskip=3pt,belowskip=3pt,
  boxpos=c,showspaces=false,showtabs=false,tabsize=4,breaklines=true,
  columns=flexible,mathescape}
% RoleModel
\lstdefinelanguage{Roles}{
  keywords={RoleModel, ROLE},
  keywords=[2]{input, super, transitive, reflexive,optional},morestring=[s]{[}{]}} 
\lstdefinestyle{Roles}{language=Roles,keywordstyle=\color{role}\bfseries,
  keywordstyle= [2]\color{roleKeyword}}

\usetikzlibrary{positioning}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{shapes}
\usetikzlibrary{graphs}
\usetikzlibrary{quotes}

\newsavebox\mybox

\begin{document}

\definecolor{role}{cmyk}{1.0, 0.417, 0.0, 0.247}
\definecolor{roleKeyword}{cmyk}{0.3, 0.7, 0.0, 0.373}

\tikzset{
  role/.style = {rounded rectangle, minimum size=6mm, very thick, draw=role,
    top color=white,bottom color=role!20, font=\sffamily\scriptsize,
    align=center,text=black},
  skip loop/.style = {to path={-- ++(0,#1) -| (\tikztotarget)}},
  hv/.style = {to path={-| (\tikztotarget) \tikztonodes}},
  vh/.style = {to path={|- (\tikztotarget) \tikztonodes}},
  comp/.style = {Diamond-},
  ass/.style = {-{Straight Barb[angle'=45,round]}},
  imp/.style = {-{Triangle[open,length=7pt]}},
  proh/.style = {{Bar[sep=1pt]}-{Bar[sep=1pt]}}
}

\begin{figure}
% Speichern des Listings in einer Box
  \savebox\mybox[0.45\textwidth]{%
    \lstinputlisting[style=Roles]{repres.role}%
  }
  \centering
  \subfloat[Graphical representation.]{
    \label{subfig:RolesGraph}
% Einfügen des Bildes in einer varwidth oder minipage Umgebung mit gleicher Höhe
% wie das Listing
    \begin{varwidth}[c][\dimexpr\ht\mybox+\dp\mybox\relax][c]{0.45\linewidth}
      \begin{tikzpicture}[
        node distance=9mm and 0mm,
        thick,black!50,
        every edge/.style={
          rounded corners,
          draw=black!50,
          text=black,
          font=\sffamily\scriptsize,
          near end
        }]
        \node[role] (ContainerContainer) {ContainerContainer};
        \node[role] (OriginalContainer) [below left=of ContainerContainer] {OriginalContainer};
        \node[role] (NewContainer) [below right=of ContainerContainer] {NewContainer};
        \node[role] (Extractee) [below right=of OriginalContainer,xshift=15pt] {Extractee};
        \path
          (ContainerContainer) edge[comp,hv,"target"] (NewContainer)
          (ContainerContainer) edge[comp,hv,"source"] (OriginalContainer)
          (NewContainer) edge[comp,vh,"moved"] (Extractee)
          (OriginalContainer) edge[ass] node[above,xshift=-5pt] {reference} (NewContainer)
          (OriginalContainer) edge[comp,vh] node[below] {extracts}(Extractee);
      \end{tikzpicture}
    \end{varwidth}
  }
  \qquad
  \subfloat[Textual representation.]{
      \label{subfig:RolesText}
      \usebox\mybox% Ausgabe der Box mit dem Listing
  }
  \caption{Different representations.}
  \label{fig:representations}
\end{figure}

\end{document}

alt text

Permanenter link

beantwortet 27 Mai '14, 15:17

esdd's gravatar image

esdd
17.8k284257
Akzeptiert-Rate: 62%

bearbeitet 27 Mai '14, 17:16

Ich danke dir vielmals! So funktioniert es super. Eine Bitte hätte ich noch. Kannst du mir erklären, was die Befehle in der Breitenangabe \dimexpr\ht\mybox+\dp\mybox\relax genau machen? Intuitiv würde ich sagen, dass \ht\mybox die Höhe der Box mybox nimmt. Aber was bedeutet das genau?

(27 Mai '14, 16:44) ErnstZ

\dimexpr erlaubt die Berechnung eines dimensionsbehafteten Ausdrucks und erwartet ein \relax an dessen Ende. \ht\mybox entspricht der Höhe der Box \mybox, in die zuvor das Listing gespeichert wurde. Diese Box hat aber außerdem eine Tiefe, die über \dp\mybox ermittelt wird und zur Höhe addiert wird.

Siehe auch Was macht relax?

(27 Mai '14, 17:29) esdd

Sorry, dass ich da nochmal nachhake, aber nach meinem bisherigen Verständnis haben räumliche Objekte Höhe, Breite und Tiefe. Das Listing hier liegt doch aber nur in der Ebene, hat also nur eine Breite und eine Höhe. Was genau ist denn mit Tiefe gemeint?

(28 Mai '14, 09:37) ErnstZ

Wenn man die Box mit dem Listing einfach in einen normalen Text einfügt, dann liegt ein Teil der Box oberhalb der Grundlinie (Höhe)und der Rest unterhalb der Grundlinie (Tiefe). Die Gesamthöhe der Box ist dann die Summe aus Höhe und Tiefe.

(28 Mai '14, 10:53) esdd

Verstehe, vielen Dank!

(28 Mai '14, 10:54) ErnstZ

Nur eine schnelle Idee und vielleicht nicht die beste, aber Du könntest das alles einfach in eine tabular mit m-Spalten setzen.

alt text

Open in writeLaTeX
\begin{figure}
  \centering
  \begin{tabular}{*{2}{m{.45\linewidth}}}
    <Bild> &
    <Code> \\
    <Beschriftung Bild> &
    <Beschriftung Code>
  \end{tabular}
  \caption{Different representations.}
  \label{fig:representations}
\end{figure}

Ich hab statt subfig das Paket subcaption verwendet, da es ermöglicht, Captions getrennt vom Bild einzusetzen. So sind denn auch die Captions einfach in der nächsten Tabellenzeile.

Hier der komplette Code:

Open in writeLaTeX
\documentclass{scrartcl}

\usepackage{listings}

\lstset{
  numbers=none,
  frame=none,
  backgroundcolor=,
  basicstyle=\ttfamily\footnotesize,
  captionpos=b,
  escapeinside={@}{@},
  aboveskip=7pt,
  abovecaptionskip=3pt,
  belowskip=3pt,
  boxpos=c,
  showspaces=false,
  showtabs=false,
  tabsize=4,
  breaklines=true,
  columns=flexible,
  mathescape
}

\lstdefinelanguage{Roles}{
  keywords={RoleModel, ROLE},
  keywords=[2]{input, super, transitive, reflexive, optional},
  morestring=[s]{[}{]}
} 
\lstdefinestyle{Roles}{
  language=Roles,
  keywordstyle=\color{role}\bfseries,
  keywordstyle=[2]\color{roleKeyword}
}

\usepackage{tikz}
\usetikzlibrary{positioning,arrows.meta,shapes,graphs,quotes}

\definecolor{role}{cmyk}{1.0, 0.417, 0.0, 0.247}
\definecolor{roleKeyword}{cmyk}{0.3, 0.7, 0.0, 0.373}

\tikzset{
  role/.style = {
    rounded rectangle,
    minimum size=6mm,
    very thick,
    draw=role,
    top color=white,
    bottom color=role!20,
    font=\sffamily\scriptsize,
    align=center,
    text=black
  },
  skip loop/.style = {to path={-- ++(0,#1) -| (\tikztotarget)}},
  hv/.style = {to path={-| (\tikztotarget) \tikztonodes}},
  vh/.style = {to path={|- (\tikztotarget) \tikztonodes}},
  comp/.style = {Diamond-},
  ass/.style = {-{Straight Barb[angle'=45,round]}},
  imp/.style = {-{Triangle[open,length=7pt]}},
  proh/.style = {{Bar[sep=1pt]}-{Bar[sep=1pt]}}
}

\usepackage{subcaption,array}

\begin{document}

\begin{figure}
  \centering
  \begin{tabular}{*{2}{m{.45\linewidth}}}
    \begin{tikzpicture}[
      node distance=9mm and 0mm,
      thick,black!50,
      every edge/.style={
        rounded corners,
        draw=black!50,
        text=black,
        font=\sffamily\scriptsize,
        near end
      }]
      \node[role] (ContainerContainer) {ContainerContainer};
      \node[role] (OriginalContainer) [below left=of ContainerContainer] {OriginalContainer};
      \node[role] (NewContainer) [below right=of ContainerContainer] {NewContainer};
      \node[role] (Extractee) [below right=of OriginalContainer,xshift=15pt] {Extractee};
      \path
        (ContainerContainer) edge[comp,hv,"target"] (NewContainer)
        (ContainerContainer) edge[comp,hv,"source"] (OriginalContainer)
        (NewContainer) edge[comp,vh,"moved"] (Extractee)
        (OriginalContainer) edge[ass] node[above,xshift=-5pt] {reference} (NewContainer)
        (OriginalContainer) edge[comp,vh] node[below] {extracts}(Extractee);
    \end{tikzpicture}
  &
    \lstinputlisting[style=Roles]{repres.role}
  \\
    \subcaption{Graphical representation.\label{subfig:RolesGraph}} &
    \subcaption{Textual representation.\label{subfig:RolesText}}
  \end{tabular}
  \caption{Different representations.}
  \label{fig:representations}
\end{figure}

\end{document}

Edit: da das subcaption Paket zum caption Bündel gehört kann man auch dessen fähigkeiten zur Layout-Beeinflussung verwenden. Wenn man beispielsweise für die konkrete Abbildung die Beschriftungen näher an die Abbildung heranschieben will, dann könnte man das durch Setzen der Option skip erreichen:

Open in writeLaTeX
\begin{figure}
  \centering
  \captionsetup{skip=-15pt}
  \captionsetup[subfigure]{skip=-20pt}
  ...

alt text

Ob das auch als dokumentweite Option günstig ist, lässt sich schwer beurteilen (obwohl ich das eher bezweifle). Hier bleibt es durch die figure-Umgebung lokal auf diese Abbildung begrenzt. Man könnte natürlich global einfach auch einen anderen Wert setzen und dennoch konkret bei der Abbildung wieder anpassen.

Permanenter link

beantwortet 26 Mai '14, 19:45

cgnieder's gravatar image

cgnieder
22.1k253463
Akzeptiert-Rate: 60%

bearbeitet 27 Mai '14, 22:17

Erstmal danke für deine Lösung. Sie funktioniert für das obige Beispiel ganz gut, allerdings kann ich sie trotzdem nicht in meinem eigentlichen Dokument verwenden, da mir angezeigt wird, dass packages subcaption und subfig nicht kompatibel zueinander sind und nicht gleichzeitig verwendet werden können. Subfig benötige ich aber an anderen Stellen trotzdem definitiv noch.

(27 Mai '14, 12:42) ErnstZ

Bist Du Dir da ganz sicher, dass Du subfig brauchst? Eigentlich kann man alles, was es bereitstellt, auch mit subcaption erreichen...

(27 Mai '14, 12:51) cgnieder

um auf deine andere Frage zu antworten Clemens: ich finde subfig konsistenter bzw. eleganter, da es die voreingestellten Caption-Abstände beachtet. Per Tabular und subcaption ist es halt wirklich nur ein Workaround und die Abstände sind erstmal die der tabular.

(27 Mai '14, 13:32) ErnstZ

@ErnstZ subcaption ist Teil des caption-Bündels, das insgesamt wohl als in sich sehr konsistent und insgesamt als sehr umfassend alles, was Beschriftungen angeht, einzustufen ist. Der Autor hat jahrelange Erfahrung mit dem ganzen Thema und die Pakete sind umfassend auf Kompatibilität mit den verschiedensten Klassen getestet. Das einzige, was sich dem Bündel vorwerfen ließe, ist, dass nicht alle Features und Optionen dokumentiert sind. Der Autor ist sich dessen aber bewusst. (Handbücher zu schreiben ist auch wirklich eine mühsame Arbeit und kostet viel Zeit...)

(27 Mai '14, 13:45) cgnieder

Meine Antwort ist aber auch nur ein Vorschlag... wenn er Dir nicht völlig passt: vielleicht gibt es ja noch weitere Antworten :) Es ist übrigens keine gute Idee, Codeblöcke in Kommentaren zu posten: das hat den Effekt, dass nur noch die ersten sechs Kommentare angezeigt werden und die weiteren nicht mehr zu sehen sind...

(27 Mai '14, 13:47) cgnieder

Ja, das möchte ich gar nicht bezweifeln. Aber was sagst du zu den Abständen, die durch eine Tabular dann doch anders sind?

(27 Mai '14, 13:47) ErnstZ
1

@ErnstZ ich habe Deinen Kommentar mit dem Code entfernt, damit man die anderen Kommentare wieder lesen kann ... die Abstände schaue ich mir später nochmal an und sag dann vielleicht was und kann meine Antwort ergänzen.

(27 Mai '14, 20:51) cgnieder

Alles klar. Habe ich auch schon mitbekommen, dass mein Kommentar nicht mehr zu sehen war. Nun weiß ich Bescheid für die Zukunft.

(28 Mai '14, 09:34) ErnstZ
Ergebnis 5 von 8 show 3 more comments
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×730
×4

gestellte Frage: 26 Mai '14, 17:20

Frage wurde gesehen: 10,996 Mal

zuletzt geändert: 28 Mai '14, 10:54