PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : pgfplots "Dimension too large" Fehler



Curryhunter
07-02-2013, 16:02
Hallo Ihr,
ich hab mal ein "Mini"-Bsp. angehängt, welches den Fehler zeigt.

Ich fitte meine Messwerte mittels gnuplot und erhalte Fitparameter, welche ich in dat-Dateien ablege. Nun soll pgfplots diese Werte auslesen und in der Legende in die zum Fitten genutzte Funktion einsetzen. Dies klappt auch normalerweise, nur bei den neueren Messungen werden die Parameter wohl zu groß für pgfplots/TeX.

Der Fehler wird also durch die erste Zahl in der Datei parameter.dat (4.451e+004) beim Einlesen/Verarbeiten durch pgfplots verursacht. Verkleinert man die Zahl (z.B. auf 4451) klappts. Der richtige Wert ist übrigens 44513, falls das interessiert.

Wie kann ich pgfplots bzw TeX dazu bewegen, auch diese Zahl zu verwenden?

Danke schonmal für Eure Mühe!
Grüße
Stefan


Hier mal das Beispiel:


\documentclass{scrartcl}
\usepackage[latin1]{inputenc}

\usepackage[T1]{fontenc}
\usepackage{filecontents}
\begin{filecontents}{parameter.dat}
4.451e+004;8.800e+004 %die erste Zahl hier ist zu groß? Die zweite Zahl in der Spalte verwende ich nicht.
-587.839;33.491
-1.215;0.339
696.359;0.0
\end{filecontents}
\begin{filecontents}{messwerte.dat}
961;29
960;30
908;42
906;42
858;48
859;50
808;64
809;65
754;86
744;96
729;110
743;102
716;137
712;121
692;160
689;143
667;253
664;207
\end{filecontents}
\begin{filecontents}{fitting.dat}
# Curve 0 of 1, 100 points
# Curve title: "f(x)"
# x y type
6.6400000e+002;2.3060659e+002;;i
7.0000000e+002;1.4410564e+002;;i
7.2100000e+002;1.1698983e+002;;i
7.4800000e+002;9.3488696e+001;;i
7.5100000e+002;9.1404937e+001;;i
7.9300000e+002;6.9205355e+001;;i
8.3800000e+002;5.4391307e+001;;i
8.6200000e+002;4.8663566e+001;;i
8.8000000e+002;4.5046376e+001;;i
9.0100000e+002;4.1404176e+001;;i
9.2200000e+002;3.8265367e+001;;i
9.4000000e+002;3.5902922e+001;;i
9.5500000e+002;3.4129216e+001;;i
9.6100000e+002;3.3463829e+001;;i
\end{filecontents}
\usepackage{amsmath}

\usepackage{graphicx}

\usepackage{siunitx}

\usepackage{lmodern}

\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{external}
\usetikzlibrary{pgfplots.external}
\tikzexternalize[shell escape=-enable-write18]
\tikzset{external/optimize command away=\myExpensiveMacro}
\tikzsetexternalprefix{PGFPlots/}
\tikzset{external/force remake} %Force Remake of the Graphs!

\newcount\kencounter
\global\kencounter=0

\pgfplotstableset{col sep=semicolon}

\pgfplotsset{
compat=1.5.1,
label style={font=\small},
tick label style={font=\small},
legend style={font=\footnotesize},
every mark/.append style={solid},
every axis/.append style={
% line width=0.1pt,
font=\small,
thick,
tick style={thick,black}
}
}
\pgfkeys{/pgf/number format/.cd,
%fixed,
%fixed zerofill,
%precision=2,
set thousands separator={},
}

\begin{document}
\begin{figure}[H]
\begin{tikzpicture}
\pgfplotsset{log base 10 number format code/.code={$\pgfmathparse{10^(#1)}\pgfmathprintnumber{ \pgfmathresult}$}} %um keine 10^x auszugeben
\begin{axis}[
title={},
width=1\textwidth,
height=0.45\textheight,
thick,
xticklabel style = {/pgf/number format/.cd,fixed,precision=0},
yticklabel style = {/pgf/number format/.cd,fixed,precision=0},
%xmin=600,
%xmax=1000,
%ymin=0,
%ymax=100,
xlabel=Temperatur (\si{\celsius}),
ylabel=Zeit (\si{\milli\second}),
tick style={thick,black},
cycle list name=mark list,
%cycle list name=black white,
grid=major,
grid style={dotted,black,thin},
minor tick num=1,
legend cell align=left,
legend style={at={(0.99,0.99)},anchor=north east,font=\small}
]
\addplot+[only marks] table[x index=0,y index=1]{messwerte.dat};
\addlegendentry{Versuchsreihe};
\addplot+[smooth] table[x index=0,y index=1]{fitting.dat};
\addlegendentry{\pgfplotstableread{parameter.dat}\ parameters
\pgfplotstablegetelem{0}{0}\of\parameters \pgfmathsetmacro\paramA{\pgfplotsretval}
\pgfplotstablegetelem{1}{0}\of\parameters \pgfmathsetmacro\paramB{\pgfplotsretval}
\pgfplotstablegetelem{2}{0}\of\parameters \pgfmathsetmacro\paramC{\pgfplotsretval}
\pgfplotstablegetelem{3}{0}\of\parameters \pgfmathsetmacro\paramD{\pgfplotsretval}
$\pgfmathprintnumber[sci]{\paramA}\left({x}+{\pgfmathprintnumber{\paramB}}\ right)^{\pgfmathprintnumber{\paramC}}$
}
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}

bobmalaria
08-02-2013, 12:10
hi,

ich kann leider auch nicht genau sagen was da abgeht.
wenn man aber mal die parameter tabelle einliest und dann ausgibt, dann stimmt alles.

wenn man dann aber das ergebnis ans macro \paramA uebergeben will, dann geht was schief. was genau weiss ich nicht. eventuell weil pgfmath versucht das ergebnis in \pgfsetmacro irgendwie zu runden und pgf hat aufgrund der limitierungen von latex keine allzu gute gleitkommaberechnung.

eventuell kannst du das irgendwo einstellen, dass alle dezimanstellen ausgegeben werden und dann stolpert das macro vielleicht nicht mehr.

lange rede kurzer sinn, du brauchst das nicht wiklich und kannst einfach das ergebnis per \let an \paramA uebergeben denn eigentlich stimmt es ja schon.


\documentclass{scrartcl}
\usepackage[latin1]{inputenc}

\usepackage[T1]{fontenc}
\usepackage{filecontents}
\begin{filecontents}{parameter.dat}
4.451e+004;8.800e+004
-587.839;33.491
-1.215;0.339
696.359;0.0
\end{filecontents}
\begin{filecontents}{messwerte.dat}
961;29
960;30
908;42
906;42
858;48
859;50
808;64
809;65
754;86
744;96
729;110
743;102
716;137
712;121
692;160
689;143
667;253
664;207
\end{filecontents}
\begin{filecontents}{fitting.dat}
# Curve 0 of 1, 100 points
# Curve title: "f(x)"
# x y type
6.6400000e+002;2.3060659e+002;;i
7.0000000e+002;1.4410564e+002;;i
7.2100000e+002;1.1698983e+002;;i
7.4800000e+002;9.3488696e+001;;i
7.5100000e+002;9.1404937e+001;;i
7.9300000e+002;6.9205355e+001;;i
8.3800000e+002;5.4391307e+001;;i
8.6200000e+002;4.8663566e+001;;i
8.8000000e+002;4.5046376e+001;;i
9.0100000e+002;4.1404176e+001;;i
9.2200000e+002;3.8265367e+001;;i
9.4000000e+002;3.5902922e+001;;i
9.5500000e+002;3.4129216e+001;;i
9.6100000e+002;3.3463829e+001;;i
\end{filecontents}
\usepackage{amsmath}

\usepackage{graphicx}

\usepackage{siunitx}

\usepackage{lmodern}

\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{external}

\pgfplotstableset{col sep=semicolon}

\pgfplotsset{
compat=1.5.1,
label style={font=\small},
tick label style={font=\small},
legend style={font=\footnotesize},
every mark/.append style={solid},
every axis/.append style={
% line width=0.1pt,
font=\small,
thick,
tick style={thick,black}
}
}
\pgfkeys{/pgf/number format/.cd,
%fixed,
%fixed zerofill,
%precision=2,
set thousands separator={},
}

\begin{document}
\begin{figure}[H]
\begin{tikzpicture}
\pgfplotsset{log base 10 number format
code/.code={$\pgfmathparse{10^(#1)}\pgfmathprintnumber{ \pgfmathresult}$}} %um
%keine 10^x auszugeben
\begin{axis}[
title={},
width=1\textwidth,
height=0.45\textheight,
thick,
xticklabel style = {/pgf/number format/.cd,fixed,precision=0},
yticklabel style = {/pgf/number format/.cd,fixed,precision=0},
%xmin=600,
%xmax=1000,
%ymin=0,
%ymax=100,
xlabel=Temperatur (\si{\celsius}),
ylabel=Zeit (\si{\milli\second}),
tick style={thick,black},
cycle list name=mark list,
%cycle list name=black white,
grid=major,
grid style={dotted,black,thin},
minor tick num=1,
legend cell align=left,
legend style={at={(0.99,0.99)},anchor=north east,font=\small}
]
\addplot+[only marks] table[x index=0,y index=1]{messwerte.dat};
\addlegendentry{Versuchsreihe};
\addplot+[smooth] table[x index=0,y index=1]{fitting.dat};
\addlegendentry{%
\pgfplotstableread{parameter.dat}\parameters
\pgfplotstablegetelem{0}{0}\of\parameters
\let\paramA\pgfplotsretval
\pgfplotstablegetelem{1}{0}\of\parameters
\let\paramB\pgfplotsretval
\pgfplotstablegetelem{2}{0}\of\parameters
\let\paramC\pgfplotsretval
\pgfplotstablegetelem{3}{0}\of\parameters
\let\paramD\pgfplotsretval
$\pgfmathprintnumber[sci]{\paramA}\left({x}+{\pgfmathprintnumber{\paramB}}
\right)^{\pgfmathprintnumber{\paramC}}$}
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}

http://www.mrunix.de/forums/attachment.php?attachmentid=5598&stc=1&d=1360321621

Curryhunter
08-02-2013, 12:17
Danke Dir bobmalaria!

Das löst mein Problem!

bobmalaria
08-02-2013, 12:23
hi,

gerne, gerne

um solche fehler besser einzugrenzen wuerde ich dir empfehlen nicht so zu schalchteln.
lese die tabelle z.b. gleich nach \begin{figure} ein ansatt in \addlegendentry.
dann macht der ausgegebene fehler vielleicht mehr sinn. ich bin auch erst drauf gekommen
als ich den ganzen plott erstmal weg gelassen habe.

aus persoenlichem interesse wuerde mich noch dein gnuplot auf aufruf interessieren mit dem du die fitting parameter in eine datei schreibst. ich verwende es nciht oft, aber ab und an waehre das ganz nett.

gruss

Curryhunter
08-02-2013, 12:41
Hi,
da der Code so über die Tage gewachsen ist und ich z.B. den Teil zum Einlesen der Legende auch nur aus nem anderen Foreneintrag übernommen hab, steht das wohl etwas ungeordnet und verschachtelt da. Wobei ich es zum Nachvollziehen des Codes einfacher finde, wenn alles da steht, wo es auch verarbeitet wird. Zum fehlersuchen ist es wohl nicht so gut.

Der gnuplot-Aufruf:

\addplot+[raw gnuplot, blue, mark=none, line width=1.5, id=B2-fit] gnuplot {
set datafile separator ';';
f(x)=a*(x+b)**c;
a=100;
b=-650;
c=-1;
set fit errorvariables;
fit f(x) 'Pfad zur Datei' using 1:2 via a,b,c;
plot [665:963] f(x);
set print "parameter.dat";
print a,';', a_err;
print b,';', b_err;
print c,';', c_err;
};

Feuersaenger
08-02-2013, 23:12
Hallo,

Die Loesung von bobmalaria ist auf jeden Fall die richtige.

Zur Erlaeuterung in dem vorliegenden Fall ist die Schwierigkeit, dass \pgfmathparse in der default-konfiguration lediglich einen Datenbereich von -16000 ... 16000 unterstuetzt -nicht mehr. Und \pgfmathsetmacro ist dasselbe wie \pgfmathparse (es schreibt das resultat lediglich woanders hin als \pgfmathparse). In dem vorliegenden Fall ist \let voellig ausreichend, da es nur den Wert kopiert ohne irgendwas zu interpretieren oder zu rechnen.

Im Gegensatz zu \pgfmathparse kann \pgfmathprintnumber den kompletten Datenbereich von IEEE double (sogar etwas mehr) abdecken. Darum kann die Zahl problemlos dargestellt werden.

Sollten Arithmetik mit \pgfmathparse betreiben werden, kann dies mit

\pgfkeys{/pgf/fpu}
\pgfmathparse{...}

durchgefuehrt werden - dann hat auch \pgfmathparse eine floating point unit und arbeitet auf dem erwarteten Datenbereich. Das ist typischerweise nur in speziellen Anwendungen sinnvoll (also nicht als globale Einstellung oder so).

Mit liebem Gruss

Christian