SVG Plots mit Spline Interpolation

Begonnen von eki, 19 Januar 2015, 14:05:33

Vorheriges Thema - Nächstes Thema

justme1968

schaut gut aus.

auch die achsen gehen wieder.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Mr.Heat

Hallo,

ich weiß nicht, was ich sonst helfen kann, um eine bessere Glättung zu bekommen, deshalb bin ich mal so frei und hänge den (garnicht so großen) Sourcecodeteil an, in dem gnuplot (erfolgreich) csplines aus meinen Daten rechnet; es ist von https://github.com/gnuplot/gnuplot/blob/master/src/contour.c#L1041.

Wenn jemand in diesem Thema drin ist, kann er vielleicht ohne größeren Aufwand da rauslesen, was dort anders gemacht wird? Wenn es nicht hilft, muss ich mich halt damit abfinden, eckige Kurven zu haben und auf die hübsche Glättung zu verzichten =)

LG

eki

Einen Algorithmus zu finden, der uns so etwas wie in Deinem Bild berechnet, sollte nicht so schwer sein. Das hilft hier aber leider nichts.
Wenn wir das Gnuplot mäßig machen würden, dann müssten wir auf dem Server relativ viele nahe beieinander liegende Punkte rechnen, die einen schönen weichen Verlauf der Kurve ergäben. Clientseitig würden dann nur Linien geplottet (mit dem Nachteil, dass Serverseitig viel gerechnet werden muss und jede Menge Daten zu übertragen wären).
Mein Ansatz war daher, wir nutzen die in SVG enthaltene Interpolationsmethode (nutzt leider keine Splines sonder Bezier Kurven). Der Vorteil ist, wir müssen auf dem Server nur für die eigentlichen Messpunkte auf schlaue Weise die Kontrollpunkte rechnen und auch nur die übertragen. Den Rest macht dann der Client im Browser.
Die Methode von Gnuplot irgendwie zu analysieren bringt also nicht viel, das das mathematisch wenig mit meinem Ansatz zu tun hat.
Offensichtlich ist die von mir gefundene und implementierte Methode bei nicht gleichmäßiger Verteilung der Punkte auf der x-Achse nicht so richtig schlau. Ich mache mir noch einmal ein paar Gedanken, das kann aber schon ein wenig dauern. Falls mir noch was schlaueres einfällt, melde ich mich.

rudolfkoenig

Ich habe die logproxy Demos von andre ins fhem.cfg.demo mit kleinen aenderungen uebernommen, und nach laengerem nachdenken und experimentieren das cubic/quadratic an einen fiktiven "predicted" Linie in dem vorhandenen Plot demonstriert.

Dabei ist mir aufgefallen, dass bei quadraticSmooth:
- die Linie am Schluss immer zu Null gebogen wird
- bei Daten mit vielen Punkten es genauso "haarig" ist, wie ohne eine spezielle Behandlung, siehe screenshot. Lohnt sich diese spezielle Behandlung trotzdem?

Ich habe die letzte Version der SVG eingecheckt, aber
- den letzten split im SVG_render (was mAn zu teuer ist) durch ein regexp ersetzt
- falls die Quelle nur ein Datenpunkt sendet, die Ausgabe geloescht, sonst kriegt man eine Fehlermeldung.

eki

#64
Das mit dem letzten Punkt bei quadraticSmooth war noch ein Fehler.
In Zeile 1907 muss stehen:
      $ret .= sprintf(" %d,%d", $x1, $y1) if(($lt eq "T") && defined($x1));
      anstatt
      $ret .= sprintf(" %d,%d", $x1, $y+$h) if(($lt eq "T") && defined($x1));

Was meinst Du mit "spezielle Behandlung"?.

Kannst Du mir die Daten zu Deinem Bild posten?

rudolfkoenig

ZitatWas meinst Du mit "spezielle Behandlung"?.
Na SVG_calcControlPoints() & co.

ZitatKannst Du mir die Daten zu Deinem Bild posten?
Ist Teil der fhem.cfg.demo, siehe auch
Zitatsvn co https://svn.code.sf.net/p/fhem/code/trunk/fhem

eki

Ich denke die spezielle Behandlung lohnt sich trotzdem, sonst ist es ja auch bei wenigen Punkten "haarig". Außerdem wird das SVG_calcControlPoints() bei quadraticSmooth ja gar nicht genutzt.

Eventuell könnte das Problem bei vielen Punkte und quadraticSmooth an der Rundung liegen. Wenn man die sprintf statements mit %.1f statt mit %d und ohne die int(...+0.5) Rundung verwendet sehen Plots mit vielen Punkte bei mir auf jeden fall besser aus.
Source ist angehängt

rudolfkoenig

Habe deine Aenderungen eingecheckt, aber das demo Plot bleibt haarig. Selbst nachdem ich bei der $x1/$y1 Berechnung das int entferne, und statt %0.1f das %f mit 6 Nachkommastellen verwende.

Ich wuerde es dabei belassen, man sieht ja sofort, dass es haarig wird, wird also keiner "betrogen".

eki

OK.
Mehr als %.1f macht keinen Sinn, da ja nur ein int durch zwei geteilt wird, und da kann es ja höchstens ein .5 nach dem Koma geben.

Hat Spaß gemacht, auch mal sebst in die Tiefen von fhem abzutauchen.

eki

Es hat mich doch nicht so ganz in Ruhe gelassen, dass die Plots in einigen Fällen "haarig" aussahen. Nach einiger Suche habe ich einen alternativen Ansatz gefunden, um die Kontrollpunkte zu berechnen. Ergibt zumindest bei mir mit "cubic" auch bei "anspruchsvoller Datenbasis" (z.B. aus dem fhem.cfg.demo) sehr gute Ergebnisse ("quadratic" funktioniert zwar auch besser, ist aber immer noch nicht optimal, "quadraticSmooth" habe ich erst mal so gelassen wie es war).
98_SVG.pm ist angehängt (Basis war die Version 7819 von heute Morgen).

rudolfkoenig


nccfast

Hallo eki,
ganz was anderes:
Wie nhast du deine Wettervorhersage von Seite 1 eingebaut?
Hast du evtl das cfg davon ...

willybauss

Hi,

ich bin mir nicht sicher, ob ich hier richtig bin ==> bitte nicht hauen  ;) ...

Ich habe grade festgestellt, dass die im SVG angezeigten Werte meiner Innentemperatur ('Display Plot Values' Funktion) alle einen Offset von 0,1° haben bezogen auf die Daten im Logfile, also

Logfile = 21,4°C
'Display Plot Values'  zeigt 21,5°C

Das ist reproduzierbar über längere Zeiträume. Der  'Display Plot Values' Wert ändert sich über der Zeit genau so wie der Wert im Logfile, behält dabei immer den Offset von 0,1° bei.

==> Bug or Feature?
FHEM auf Raspberry Pi B und 2B; THZ (THZ-303SOL), CUL_HM, TCM-EnOcean, SamsungTV, JSONMETER, SYSMON, OBIS, STATISTICS

rudolfkoenig

Bug, aber eins was vermutlich nicht einfach zu aendern ist.
Das SVG-Perl Modul berechnet/rundet die Daten soweit, dass es auf dem Bildschirm noch richtig angezeigt wird, damit man nicht ueberfluessige Nachkommastellen ueber die Leitung reisen. Das JavaScript im Browser versucht aus den Daten die Werte zurueckzurechnen.

willybauss

ok, verstehe.

Das führt mich aber zu einer anderen Frage: Im Header der Plots lasse ich mir ein paar Werte anzeigen, z.B. mit

attr Mythz_Plot2_HC1Offset_Integral label "HC1Soll-HC1Ist $data{currval1}K, Integralwert $data{currval2}"

Gelegentlich werden da etliche Nachkommastellen angezeigt, also z.B. 3,000000001 K.
Kann ich da was ändern, z.B. eine Rundung auf 1 Nachkommastelle?
FHEM auf Raspberry Pi B und 2B; THZ (THZ-303SOL), CUL_HM, TCM-EnOcean, SamsungTV, JSONMETER, SYSMON, OBIS, STATISTICS