pgfplots - Grafik aus .txt Datei erstellen

Tabellen und Grafiken erstellen und anordnen


dodge11
Forum-Newbie
Forum-Newbie
Beiträge: 4
Registriert: Fr 12. Jun 2015, 15:14

pgfplots - Grafik aus .txt Datei erstellen

Beitrag von dodge11 »

Hallo,

ich möchte mittels pgfplots eine Grafik erstellen, welche ihre Daten aus einer .txt-Datei bezieht.
In dieser .txt-Datei kann eine unterschiedliche Anzahl von Datensätzen sein, die sich jeweils auf eine Linie im Plot bezieht.
Die Bezeichnung dieser Datensätze ist in der Form 1.4e-4,1.4e-7,3e-8 etc., sie ist nicht zwangsläufig aufeinanderfolgend, sondern kann springen.
Jedem dieser Datensätze ist nun ein fester Marker, sowie eine feste Farbe zugeordnet (auch diese befindet sich in der .txt-Datei).

Mein Problem ist nun, dass sich Farbe und Marker nicht aus dieser Datei auslesen lassen.

Es folgt die .txt-Datei
p		x		r		er		cr		mr				
#	
1.4e-4	1.00	        0.03	       0.3		144		*
1.4e-4	10.00	0.07	       0.4		144		*	
1.4e-4	100.00	0.13	       0.5		144		*
1.4e-4	1000.00	0.50	       0.7		144		*
#
1.4e-5	1.00	        0.01	       0.8		145		+
1.4e-5	10.00	0.03	       0.02	        145		+
1.4e-5	100.00	0.08	       0.05	        145		+
1.4e-5	1000.00	0.20	       0.4		145		+
Nun mein Latex-Code:
\definecolor{144}{rgb}{0.8,0.6,0}
\definecolor{145}{rgb}{0,0,0.5}
\begin{document}
\begin{tikzpicture}
    \begin{loglogaxis}[
	xlabel = s,
	ylabel = $\frac{U_\text{2}}{I_\text{4}}$,
	ymin = 0.0001,
	ymax = 1,
	legend style={at={(1,0.95)},anchor=north west},
	legend cell align=left,
	grid = both]
		\pgfplotsinvokeforeach{1.4e-4,1.4e-5,1.4e-7}
		{
		\addplot +[mark=+,color=144,error bars/.cd,x dir=both,y dir=both,y explicit relative,]table[x=x,y=r,restrict expr to domain={\thisrowno{0}}{#1:#1},y error=er,restrict expr to domain={\thisrowno{0}}{#1:#1}] {test.txt};
		\addlegendentry{#1\, V}
		}
	\end{loglogaxis}
\end{tikzpicture}
Dieser Code ist lauffähig, jedoch ist der Marker und die Farbe jeder Linie gleich.
Es wäre nett, wenn mir jemand zeigen könnte, wie ich nun die aus der .txt-Datei ausgelesenen Farben (cr) und Marker (mr) in den entsprechenden addplot-Befehl einbinden könnte.

Vielen Dank für Eure Hilfe.

feuersaenger
Forum-Fortgeschrittener
Forum-Fortgeschrittener
Beiträge: 91
Registriert: Mi 5. Okt 2011, 18:24
Wohnort: Rheinbach

Beitrag von feuersaenger »

Hallo,

Um marker individuell (d.h. fuer jeden datenpunkt anders) einzufaerben gibt es das kommando "scatter". Sobald das aktiv ist, wird jeder Datenpunkt anders gemacht. Tatsaechlich wird so auch die marker Form anpassbar.

Wenn man allerdings sowohl Farbe als auch marker Form individuell anpassen will, braucht man noch "visualization depends on", damit pgfplots beide verschiedene Werte bereit stellt.

In Deinem Fall ist es eigentlich keine "individuelle" Anpassung, aber aufgrund der Formulierung in dem Datenfile muss man es so angeben.

Das ganze sieht so aus:
\documentclass{standalone}

\usepackage{pgfplots}
\usepackage{amsmath}

\pgfplotsset{compat=1.12}


\begin{document}

\definecolor{144}{rgb}{0.8,0.6,0}
\definecolor{145}{rgb}{0,0,0.5}
\def\marker{*}
\begin{tikzpicture}
%\tracingmacros=2 \tracingcommands=2
    \begin{loglogaxis}[
   xlabel = s,
   ylabel = $\frac{U_\text{2}}{I_\text{4}}$,
   ymin = 0.0001,
   ymax = 1,
   legend style={at={(1,0.95)},anchor=north west},
   legend cell align=left,
   grid = both]
\pgfplotsinvokeforeach{1.4e-4,1.4e-5,1.4e-7}
{
	\addplot +[
		scatter,
		point meta=\thisrow{cr},
		visualization depends on=value \thisrow{mr} \as \marker,
		mark=\marker,
		color=144,
		%
		% also change the color for each plot segment:
		  mesh, line legend,
		  % this is needed if you use 'mesh, line legend' - a bug in
		  % pgfplots (has already been fixed):
		  legend image post style={/pgfplots/mesh=false},
		error bars/.cd,
		x dir=both,
		y dir=both,
		y explicit relative,
		]
			table[
			x=x,
		y=r,
		restrict expr to domain={\thisrowno{0}}{#1:#1},
		y error=er,
		] {test.txt};
	\addlegendentry{#1\, V}
}
   \end{loglogaxis}
\end{tikzpicture}
\end{document}
Die Zeile "mesh, line legend" mit der darauf folgenden hat nur den Zweck, jedes liniensegment _auch_ individuell einzufaerben. das ist der Zweck von "mesh": es benutzt die Farbe, die als "point meta" angegeben wird (genau dieselbe wie fuer scatter), und faerbt damit liniensegmente ein. So richtig gut klappt das nicht, denn die error bar enden sind scheinbar nicht betroffen. Ich weiss nicht, ob Du diese Zeilen haben willst.



Mit liebem Gruss

Christian[/code]
Dateianhänge
P.png
P.png (32.02 KiB) 3387 mal betrachtet

dodge11
Forum-Newbie
Forum-Newbie
Beiträge: 4
Registriert: Fr 12. Jun 2015, 15:14

Beitrag von dodge11 »

Hallo,

vielen Dank für deinen Lösungsvorschlag.

Ich habe deinen Code getestet.

Bei mir ändern sich jetzt die Marker im Plot, aber nicht in der Legende.
Die Farbe ändert sich bei mir gar nicht, es werden nur die Standardfarben verwendet.
In deinem addplot-Befehl hast du noch Color=144 drinstehen, das habe ich vorher entfernt, ich denke das es ein Tippfehler ist !?

Weiterhin habe ich noch nicht verstanden, wie du jetzt mit Point meta jedem Datensatz eine feste Farbe zuordnest.
Kannst du vielleicht dazu nochmal ein paar Informationen geben, wie genau das funktionieren soll?

Danke für deine Hilfe.

feuersaenger
Forum-Fortgeschrittener
Forum-Fortgeschrittener
Beiträge: 91
Registriert: Mi 5. Okt 2011, 18:24
Wohnort: Rheinbach

Beitrag von feuersaenger »

Hi,

Du hast recht, die marker in der legend sind nicht von 'scatter' betroffen. Tatsaechlich ist das auch eine nicht einfach loesbare Aufgabe, da legenden generell lediglich symbolisch das widerspiegeln, was im plot passiert. Technisch gibt es da zwei Ansaetze:

1. der "standard" weg waere, dass Du pro \addplot Befehl auch nur einen Datensatz hast, d.h. separate files hast und die nicht nachtraeglich auseinanderarbeiten laesst. Dann koenntest Du individuell und mit vollem Support fuer legenden etc. markeroptionen und Farben setzen. Eine Art, sowas zu machen, waere: Du behaelst die spalte "x", da sie ja fuer alle \addplot befehle ohnehin identisch ist und machst fuer jedes Experiment ne eigene Spalte. Alternativ waere der standartweg, dass Du pro \addplot eine tabelle generierst.

2. Ansonsten faellt mir aktuell nur ein, mit einem der Befehle zur Tabellenverwaltung die tabelle einzulesen, darueber zu iterieren, nach dem gewuenschten restriction wert suchen und dann "von Hand" die marker zu setzen.

Nun haben wir es hier leider mit TeX zu tun, und damit erfordert Option (2) tiefgehendes Expertenwissen, was kaum jemand hat und auch nicht so leicht vermittelbar ist. Ich empfehle Dir, dass Du nochmal ueberlegst, ob nicht der Standardweg (1) die einfachere Loesung ist... oder ob Du damit lebst, dass es zunaechst nicht gut geht und die Legende das nicht widerspiegelt.

Die Farbe aendert sich bei Dir gar nicht? Oder meinst Du die Legende? Wenn Du Dich auf die Legende beziehst, gilt hier leider auch oben gesagtes. Bei mir ist das tatsaechlich auch schwarz (das ist mir leider beim Posten nicht aufgefallen). Auch hier gilt oben skizzierter Loesungsvorschlag.


Auskunft zu "point meta" kann ich gerne geben: point meta ist der "Standard"weg von pgfplots, um einen skalaren Extrawert pro Koordinate anzugeben. Damit hat jede Koordinate die Werte (x,y,c) wobei c dann "point meta" ist. Typischerweise ist c ein skalarer "Farbwert". Dieser wird dann in die colorbar gemapped, das heisst: der kleinste solcher Farbwerte wird auf den unteresten Wert der colormap abgebildet, der groesste auf den obersten. Damit kann man leicht skalare Farbwerte (wie cr) auf Farben abbilden und kann zudem die colormap anpassen. Oder sollte ich vielleicht Deinen Anwendungsfall grob falsch verstanden haben?

Details zu "point meta" findest Du sehr ausfuehrlich im pgfplots manual (Du kannst ja mal nach scatter plots darin schauen).

dodge11
Forum-Newbie
Forum-Newbie
Beiträge: 4
Registriert: Fr 12. Jun 2015, 15:14

Beitrag von dodge11 »

Hallo,

den Standardweg 1 praktiziere ich schon, der ist aber halt leider ein bisschen umständlich und daher dachte ich, versuche das ganze ein bisschen zu Automatisieren.

Aber das scheint ja dann wohl nicht so einfach zu sein, daher würde ich es dann dabei belassen wie es war.

Die Farben in deiner Lösung ändern sich bei mir aber gar nicht, weder im Plot noch in der Legende. Bei mir wird keine der beiden definierten Farben verwendet, es werden nur die beiden Standardfarben rot und blau genutzt.

Danke für deine Hilfe.
Zuletzt geändert von dodge11 am So 14. Jun 2015, 22:12, insgesamt 1-mal geändert.

esdd
Forum-Meister
Forum-Meister
Beiträge: 2561
Registriert: So 7. Feb 2010, 16:36

Beitrag von esdd »

Du kannst auch eine cycle list verwenden. Dann musst Du nur die Marker und die Farben händisch in eine Liste eintragen. Das kannst Du entweder mit cycle list in den Optionen der axis Umgebung tun oder aber mit \pgfplotscreateplotcyclelist eine benannte Liste definieren, die Du dann über cycle list name in mehreren Plots verwenden kannst. In beiden Fällen musst Du \addplot+ verwenden. Dann "bedienen" sich die Plots der Reihe nach in der Liste.
\begin{filecontents*}{test.txt}
p      x      r      er      cr      mr             
 1.4e-4   1.00           0.03          0.3      144      * 
 1.4e-4   10.00   0.07          0.4      144      *   
 1.4e-4   100.00   0.13          0.5      144      * 
 1.4e-4   1000.00   0.50          0.7      144      * 
 1.4e-5   1.00           0.01          0.8      145      + 
 1.4e-5   10.00   0.03          0.02           145      + 
 1.4e-5   100.00   0.08          0.05           145      + 
 1.4e-5   1000.00   0.20          0.4      145      + 
\end{filecontents*}
\documentclass{standalone} 
\usepackage{amsmath}
\usepackage{pgfplots} 
\pgfplotsset{compat=1.12} 
\definecolor{144}{rgb}{0.8,0.6,0} 
\definecolor{145}{rgb}{0,0,0.5}
\begin{document} 
\begin{tikzpicture} 
  \begin{loglogaxis}[ 
      xlabel = s, 
      ylabel = $\frac{U_\text{2}}{I_\text{4}}$, 
      ymin = 0.0001, 
      ymax = 1, 
      legend style={at={(1,0.95)},anchor=north west}, 
      legend cell align=left, 
      grid = both,
      cycle list={{mark=*,144},{mark=+,145}}
    ] 
    \pgfplotsinvokeforeach{1.4e-5, 1.4e-4}{ 
      \addplot+[error bars/.cd,x dir=both,y dir=both,y explicit relative,]
        table[x=x,y=r,restrict expr to domain={\thisrowno{0}}{#1:#1},y error=er,log basis x=10]
        {test.txt}; 
      \addlegendentry{#1\, V}
    }
  \end{loglogaxis} 
\end{tikzpicture} 
\end{document}
oder


\begin{filecontents*}{test.txt}
p      x      r      er      cr      mr             
 1.4e-4   1.00           0.03          0.3      144      * 
 1.4e-4   10.00   0.07          0.4      144      *   
 1.4e-4   100.00   0.13          0.5      144      * 
 1.4e-4   1000.00   0.50          0.7      144      * 
 1.4e-5   1.00           0.01          0.8      145      + 
 1.4e-5   10.00   0.03          0.02           145      + 
 1.4e-5   100.00   0.08          0.05           145      + 
 1.4e-5   1000.00   0.20          0.4      145      + 
\end{filecontents*}
\documentclass{standalone} 
\usepackage{amsmath}
\usepackage{pgfplots} 
\pgfplotsset{compat=1.12} 
\definecolor{144}{rgb}{0.8,0.6,0} 
\definecolor{145}{rgb}{0,0,0.5}

\pgfplotscreateplotcyclelist{mylist}{%
  {mark=*,144},
  {mark=+,145}%
}

\begin{document} 
\begin{tikzpicture} 
  \begin{loglogaxis}[ 
      xlabel = s, 
      ylabel = $\frac{U_\text{2}}{I_\text{4}}$, 
      ymin = 0.0001, 
      ymax = 1, 
      legend style={at={(1,0.95)},anchor=north west}, 
      legend cell align=left, 
      grid = both,
      cycle list name=mylist
    ] 
    \pgfplotsinvokeforeach{1.4e-4, 1.4e-5}{ 
      \addplot+[error bars/.cd,x dir=both,y dir=both,y explicit relative,]
        table[x=x,y=r,restrict expr to domain={\thisrowno{0}}{#1:#1},y error=er,log basis x=10]
        {test.txt}; 
      \addlegendentry{#1\, V}
    }
  \end{loglogaxis} 
\end{tikzpicture} 
\end{document}
Gruß
Elke

dodge11
Forum-Newbie
Forum-Newbie
Beiträge: 4
Registriert: Fr 12. Jun 2015, 15:14

Beitrag von dodge11 »

Hallo,

vielen Dank für eure Lösungen, aber ich glaube, ich lasse alles so wie es ist.

Das was ich gerne hätte, lässt sich wohl so mit Latex nicht umsetzen.

Danke für Eure Hilfe.

Antworten