fertig
This commit is contained in:
@@ -13,7 +13,7 @@ class Genauigkeitsmaße:
|
||||
|
||||
Die Klasse stellt Methoden zur Verfügung für:
|
||||
|
||||
- Berechnung der a-posteriori Standardabweichung der Gewichtseinheit s₀
|
||||
- Berechnung der a-posteriori Standardabweichung der Gewichtseinheit σ̂₀
|
||||
- Berechnung des Helmertschen Punktfehlers (2D/3D),
|
||||
- Berechnung der Standardellipse (Helmertschen Fehlerellipse),
|
||||
- Berechnung der Konfidenzellipse auf Basis eines Konfidenzniveaus (alpha) mit Skalierung über die F-Verteilung,
|
||||
@@ -25,19 +25,19 @@ class Genauigkeitsmaße:
|
||||
@staticmethod
|
||||
def berechne_sigma0apost(v: np.ndarray, P: np.ndarray, r: int, print_ausgabe = True) -> float:
|
||||
"""
|
||||
Berechnet die a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
Berechnet die a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
|
||||
Die a-posteriori Standardabweichung dient als Qualitätsmaß für die
|
||||
Ausgleichung nach der Methode der kleinsten Quadrate. Dabei beschreibt
|
||||
r die Redundanz (Freiheitsgrade).
|
||||
|
||||
:param v: Residuenvektor der Beobachtungen.
|
||||
:type v: numpy.ndarray
|
||||
:type v: np.ndarray
|
||||
:param P: Gewichtsmatrix der Beobachtungen.
|
||||
:type P: numpy.ndarray
|
||||
:type P: np.ndarray
|
||||
:param r: Redundanz bzw. Anzahl der Freiheitsgrade der Ausgleichung.
|
||||
:type r: int
|
||||
:return: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:return: a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
:rtype: float
|
||||
"""
|
||||
|
||||
@@ -50,12 +50,12 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def helmert_punktfehler(Qxx, s0_apost, unbekannten_liste):
|
||||
def helmert_punktfehler(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list) -> pd.DataFrame:
|
||||
"""
|
||||
Berechnet den Helmertschen Punktfehler (2D/3D) anhand der Standardabweichungen der Koordinaten der Punkte.
|
||||
|
||||
Aus der Kofaktor-Matrix der Unbekannten Qxx werden die Kofaktoren punktweise ausgelesen. Durch Multiplikation
|
||||
mit der a-posteriori Standardabweichung der Gewichtseinheit s₀ werden die Standardabweichungen je Koordinate
|
||||
mit der a-posteriori Standardabweichung der Gewichtseinheit σ̂₀ werden die Standardabweichungen je Koordinate
|
||||
(σx, σy, σz) sowie der Helmert'sche Punktfehler σP berechnet:
|
||||
|
||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||
@@ -63,14 +63,13 @@ class Genauigkeitsmaße:
|
||||
Ergebnisse als Tabelle ausgegeben und in eine Excel-Datei exportiert.
|
||||
|
||||
:param Qxx: Kofaktor-Matrix der Unbekannten.
|
||||
:type Qxx: numpy.ndarray
|
||||
:param s0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:type Qxx: np.ndarray
|
||||
:param sigma0_apost: a-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
:type sigma0_apost: float
|
||||
:param unbekannten_liste: Liste der Unbekannten.
|
||||
:type unbekannten_liste: list
|
||||
:return: Tabelle mit Standardabweichungen und Helmertschem Punktfehler je Punkt.
|
||||
:rtype: pandas.DataFrame
|
||||
:raises ValueError: Wenn eine ungültige Dimension (nicht 2 oder 3) eingegeben wird.
|
||||
"""
|
||||
dim = int(input("Helmertscher Punktfehler (2 = 2D, 3 = 3D): "))
|
||||
diagQ = np.diag(Qxx)
|
||||
@@ -98,17 +97,17 @@ class Genauigkeitsmaße:
|
||||
except StopIteration:
|
||||
qz = 0.0
|
||||
|
||||
sx = s0_apost * np.sqrt(qx)
|
||||
sy = s0_apost * np.sqrt(qy)
|
||||
sz = s0_apost * np.sqrt(qz) if dim == 3 else 0
|
||||
sx = sigma0_apost * np.sqrt(qx)
|
||||
sy = sigma0_apost * np.sqrt(qy)
|
||||
sz = sigma0_apost * np.sqrt(qz) if dim == 3 else 0
|
||||
|
||||
sP = s0_apost * np.sqrt(qx + qy + qz)
|
||||
sP = sigma0_apost * np.sqrt(qx + qy + qz)
|
||||
|
||||
daten.append([pid, float(sx), float(sy), float(sz), float(sP)])
|
||||
except:
|
||||
continue
|
||||
helmert_punktfehler = pd.DataFrame(daten, columns=["Punkt", "σx", "σy", "σz", f"σP_{dim}D"])
|
||||
mittel_sP = helmert_punktfehler[f"σP_{dim}D"].mean()
|
||||
helmert_punktfehler = pd.DataFrame(daten, columns=["Punkt", "σ̂x", "σ̂y", "σ̂z", f"σ̂P_{dim}D"])
|
||||
mittel_sP = helmert_punktfehler[f"σ̂P_{dim}D"].mean()
|
||||
print(f"Mittlerer Helmert-Punktfehler über alle Punkte: {mittel_sP:.4f} [m]")
|
||||
display(HTML(helmert_punktfehler.to_html(index=False)))
|
||||
helmert_punktfehler.to_excel(r"Netzqualitaet\Standardabweichungen_Helmertscher_Punktfehler.xlsx",index=False)
|
||||
@@ -117,9 +116,9 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def standardellipsoid(Qxx, s0_apost, unbekannten_liste):
|
||||
def standardellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list) -> pd.DataFrame:
|
||||
"""
|
||||
Berechnet Achsenlängen des Fehlerellipsoids (a, b, c) sowie den 2D-Richtungswinkel θ aus Qxx und s₀ a posteriori.
|
||||
Berechnet Achsenlängen des Fehlerellipsoids (a, b, c) sowie den 2D-Richtungswinkel θ aus Qxx und σ̂₀ a posteriori.
|
||||
|
||||
Für jeden Punkt wird aus der Kofaktor-Matrix der Unbekannten Qxx die 3×3-Submatrix
|
||||
der Koordinaten (X, Y, Z) gebildet. Daraus werden zunächst die Standardabweichungen
|
||||
@@ -137,9 +136,9 @@ class Genauigkeitsmaße:
|
||||
Die Ergebnisse werden tabellarisch ausgegeben und in eine Excel-Datei exportiert.
|
||||
|
||||
:param Qxx: Kofaktor-Matrix der Unbekannten.
|
||||
:type Qxx: numpy.ndarray
|
||||
:param s0_apost: A-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:type Qxx: np.ndarray
|
||||
:param sigma0_apost: A-posteriori Standardabweichung der Gewichtseinheit σ̂₀.
|
||||
:type sigma0_apost: float
|
||||
:param unbekannten_liste: Liste der Unbekannten.
|
||||
:type unbekannten_liste: list
|
||||
:return: Tabelle mit Standardabweichungen (σx, σy, σz), Ellipsoid-Halbachsen (a, b, c) und Richtungswinkel θ je Punkt.
|
||||
@@ -165,18 +164,18 @@ class Genauigkeitsmaße:
|
||||
Q_sub = Qxx[np.ix_(indices, indices)]
|
||||
|
||||
# Standardabweichungen
|
||||
sx = s0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = s0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = s0_apost * np.sqrt(Q_sub[2, 2])
|
||||
sx = sigma0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = sigma0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = sigma0_apost * np.sqrt(Q_sub[2, 2])
|
||||
|
||||
# Eigenwertzerlegung
|
||||
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
||||
eigenwerte = np.sort(eigenwerte)[::-1]
|
||||
|
||||
# Halbachsen
|
||||
s_a = s0_apost * np.sqrt(eigenwerte[0]) # Große Halbachse a
|
||||
s_b = s0_apost * np.sqrt(eigenwerte[1]) # Mittlere Halbachse b
|
||||
s_c = s0_apost * np.sqrt(eigenwerte[2]) # Kleine Halbachse c
|
||||
s_a = sigma0_apost * np.sqrt(eigenwerte[0]) # Große Halbachse a
|
||||
s_b = sigma0_apost * np.sqrt(eigenwerte[1]) # Mittlere Halbachse b
|
||||
s_c = sigma0_apost * np.sqrt(eigenwerte[2]) # Kleine Halbachse c
|
||||
|
||||
# Richtungswinkel theta in gon:
|
||||
qyx = Q_sub[1, 0]
|
||||
@@ -192,10 +191,10 @@ class Genauigkeitsmaße:
|
||||
])
|
||||
except:
|
||||
continue
|
||||
standardellipsoid = pd.DataFrame(daten, columns=["Punkt", "σx [m]", "σy [m]", "σz [m]", "Halbachse a [m]", "Halbachse b [m]", "Halbachse c [m]", "θ [gon]"])
|
||||
standardellipsoid["σx [m]"] = standardellipsoid["σx [m]"].astype(float).round(4)
|
||||
standardellipsoid["σy [m]"] = standardellipsoid["σy [m]"].astype(float).round(4)
|
||||
standardellipsoid["σz [m]"] = standardellipsoid["σz [m]"].astype(float).round(4)
|
||||
standardellipsoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a [m]", "Halbachse b [m]", "Halbachse c [m]", "θ [gon]"])
|
||||
standardellipsoid["σ̂x [m]"] = standardellipsoid["σ̂x [m]"].astype(float).round(4)
|
||||
standardellipsoid["σ̂y [m]"] = standardellipsoid["σ̂y [m]"].astype(float).round(4)
|
||||
standardellipsoid["σ̂z [m]"] = standardellipsoid["σ̂z [m]"].astype(float).round(4)
|
||||
standardellipsoid["Halbachse a [m]"] = standardellipsoid["Halbachse a [m]"].astype(float).round(4)
|
||||
standardellipsoid["Halbachse b [m]"] = standardellipsoid["Halbachse b [m]"].astype(float).round(4)
|
||||
standardellipsoid["Halbachse c [m]"] = standardellipsoid["Halbachse c [m]"].astype(float).round(4)
|
||||
@@ -207,23 +206,34 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def konfidenzellipsoid(Qxx, s0_apost, unbekannten_liste, R, ausgabe_erfolgt):
|
||||
def konfidenzellipsoid(Qxx: np.ndarray, sigma0_apost: float, unbekannten_liste: list, R: int, ausgabe_erfolgt: bool) -> tuple[pd.DataFrame, float]:
|
||||
"""
|
||||
Berechnet die Konfidenzellipse für Punkte aus Qxx und einem Konfidenzniveau.
|
||||
Berechnet die Konfidenzellipsoid für Punkte aus Qxx und einem Konfidenzniveau.
|
||||
|
||||
Auf Basis der Kovarianz-Matrix der Unbekannten Qxx und der a-posteriori
|
||||
Standardabweichung der Gewichtseinheit s₀ werden für jeden Punkt die Parameter
|
||||
der Konfidenzellipse berechnet. Das Konfidenzniveau wird mittels einer Eingabe
|
||||
über alpha gewählt (Standard: 0.05 für 95%).
|
||||
Standardabweichung der Gewichtseinheit σ̂₀ werden für jeden Punkt die Parameter
|
||||
des Konfidenzellipsoids berechnet. Das Konfidenzniveau wird mittels einer Eingabe
|
||||
über alpha festgelegt (Standard: 0.05 für 95%).
|
||||
|
||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste (z.B. X1, Y1).
|
||||
Für jeden Punkt wird die 3×3-Submatrix der Koordinaten (X, Y, Z) aus Qxx gebildet.
|
||||
Über eine Eigenwertzerlegung dieser Submatrix werden die drei Hauptachsen des
|
||||
Fehlerellipsoids bestimmt. Die Halbachsen des Konfidenzellipsoids ergeben sich aus:
|
||||
|
||||
- Aₖ: große Halbachse des Konfidenzellipsoids,
|
||||
- Bₖ: mittlere Halbachse des Konfidenzellipsoids,
|
||||
- Cₖ: kleine Halbachse des Konfidenzellipsoids,
|
||||
|
||||
unter Verwendung eines Faktors aus der F-Verteilung in Abhängigkeit vom
|
||||
Konfidenzniveau und den Freiheitsgraden.
|
||||
|
||||
Die Punktzuordnung erfolgt über die Symbolnamen der Unbekanntenliste.
|
||||
Optional wird die Tabelle ausgegeben und als Excel-Datei exportiert, abhängig von
|
||||
ausgabe_erfolgt.
|
||||
|
||||
:param Qxx: Kofaktor-Matrix der geschätzten Unbekannten.
|
||||
:type Qxx: numpy.ndarray
|
||||
:param s0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0_apost: float
|
||||
:type Qxx: np.ndarray
|
||||
:param sigma0_apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type sigma0_apost: float
|
||||
:param unbekannten_liste: Liste der Unbekannten.
|
||||
:type unbekannten_liste: list
|
||||
:param R: Redundanz (Freiheitsgrade) für die F-Verteilung.
|
||||
@@ -232,7 +242,6 @@ class Genauigkeitsmaße:
|
||||
:type ausgabe_erfolgt: bool
|
||||
:return: Tabelle der Konfidenzellipse je Punkt, verwendetes alpha.
|
||||
:rtype: tuple[pandas.DataFrame, float]
|
||||
:raises ValueError: Wenn alpha nicht in (0, 1) liegt oder nicht in float umgewandelt werden kann.
|
||||
"""
|
||||
alpha_input = input("Irrtumswahrscheinlichkeit α wählen (z.B. 0.05, 0.01) [Standard=0.05]: ")
|
||||
if alpha_input.strip() == "":
|
||||
@@ -259,18 +268,18 @@ class Genauigkeitsmaße:
|
||||
Q_sub = Qxx[np.ix_(indices, indices)]
|
||||
|
||||
# Standardabweichungen
|
||||
sx = s0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = s0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = s0_apost * np.sqrt(Q_sub[2, 2])
|
||||
sx = sigma0_apost * np.sqrt(Q_sub[0, 0])
|
||||
sy = sigma0_apost * np.sqrt(Q_sub[1, 1])
|
||||
sz = sigma0_apost * np.sqrt(Q_sub[2, 2])
|
||||
|
||||
# Eigenwertzerlegung
|
||||
eigenwerte, eigenvektoren = np.linalg.eigh(Q_sub)
|
||||
eigenwerte = np.sort(eigenwerte)[::-1]
|
||||
|
||||
# Halbachsen des Konfidenzellipoid
|
||||
A_K = k * s0_apost * np.sqrt(eigenwerte[0])
|
||||
B_K = k * s0_apost * np.sqrt(eigenwerte[1])
|
||||
C_K = k * s0_apost * np.sqrt(eigenwerte[2])
|
||||
A_K = k * sigma0_apost * np.sqrt(eigenwerte[0])
|
||||
B_K = k * sigma0_apost * np.sqrt(eigenwerte[1])
|
||||
C_K = k * sigma0_apost * np.sqrt(eigenwerte[2])
|
||||
|
||||
# Richtungswinkel theta in gon:
|
||||
qyx = Q_sub[1, 0]
|
||||
@@ -288,7 +297,7 @@ class Genauigkeitsmaße:
|
||||
except:
|
||||
continue
|
||||
|
||||
konfidenzellipoid = pd.DataFrame(daten, columns=["Punkt", "σx [m]", "σy [m]", "σz [m]", "Halbachse a_k [m]", "Halbachse b_k [m]", "Halbachse c_k [m]", "θ [gon]"])
|
||||
konfidenzellipoid = pd.DataFrame(daten, columns=["Punkt", "σ̂x [m]", "σ̂y [m]", "σ̂z [m]", "Halbachse a_k [m]", "Halbachse b_k [m]", "Halbachse c_k [m]", "θ [gon]"])
|
||||
if ausgabe_erfolgt == False:
|
||||
display(HTML(konfidenzellipoid.to_html(index=False)))
|
||||
konfidenzellipoid.to_excel(r"Netzqualitaet\Konfidenzellipoid.xlsx", index=False)
|
||||
@@ -296,7 +305,7 @@ class Genauigkeitsmaße:
|
||||
|
||||
|
||||
@staticmethod
|
||||
def konfidenzellipsen_enu(a, b, ausgabe_parameterschaetzung, liste_unbekannte, ausgleichungsergebnis, s0apost, r_gesamt):
|
||||
def konfidenzellipsen_enu(a: float, b: float, ausgabe_parameterschaetzung: dict, liste_unbekannte: list, ausgleichungsergebnis: dict, sigma0apost: float, r_gesamt: int) -> tuple[pd.DataFrame, np.ndarray]:
|
||||
"""
|
||||
Berechnet Konfidenzellipsen im lokalen ENU-System aus einer ins ENU-System transformierten Qxx-Matrix.
|
||||
|
||||
@@ -317,13 +326,12 @@ class Genauigkeitsmaße:
|
||||
:type liste_unbekannte: list
|
||||
:param ausgleichungsergebnis: Dictionary der geschätzten Punktkoordinaten (XYZ) zur ENU-Referenzbildung.
|
||||
:type ausgleichungsergebnis: dict
|
||||
:param s0apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type s0apost: float
|
||||
:param sigma0apost: a-posteriori Standardabweichung der Gewichtseinheit s₀.
|
||||
:type sigma0apost: float
|
||||
:param r_gesamt: Redundanz (Freiheitsgrade) für die Konfidenzberechnung.
|
||||
:type r_gesamt: int
|
||||
:return: Tabelle der Konfidenzellipse im ENU-System, Rotationsmatrix R0 der ENU-Transformation.
|
||||
:rtype: tuple[pandas.DataFrame, numpy.ndarray]
|
||||
:raises KeyError: Wenn ``ausgabe_parameterschaetzung`` keinen Eintrag ``"Q_xx"`` enthält.
|
||||
"""
|
||||
|
||||
berechnungen = Berechnungen.Berechnungen(a, b)
|
||||
@@ -342,7 +350,7 @@ class Genauigkeitsmaße:
|
||||
# 2) Konfidenzellipoid im ENU-System
|
||||
Konfidenzellipse_ENU, alpha = Genauigkeitsmaße.konfidenzellipsoid(
|
||||
Qxx_enu,
|
||||
s0apost,
|
||||
sigma0apost,
|
||||
liste_unbekannte,
|
||||
r_gesamt,
|
||||
ausgabe_erfolgt = True
|
||||
@@ -350,16 +358,16 @@ class Genauigkeitsmaße:
|
||||
|
||||
# 3) Spaltennamen anpassen
|
||||
Konfidenzellipse_ENU = Konfidenzellipse_ENU.rename(columns={
|
||||
"σx [m]": "σE [m]",
|
||||
"σy [m]": "σN [m]",
|
||||
"σz [m]": "σU [m]",
|
||||
"σ̂x [m]": "σ̂E [m]",
|
||||
"σ̂y [m]": "σ̂N [m]",
|
||||
"σ̂z [m]": "σ̂U [m]",
|
||||
"θ [gon]": "θ_EN [gon]"
|
||||
})
|
||||
|
||||
# 4) Runden und Anzeigen
|
||||
Konfidenzellipse_ENU["σE [m]"] = Konfidenzellipse_ENU["σE [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σN [m]"] = Konfidenzellipse_ENU["σN [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σU [m]"] = Konfidenzellipse_ENU["σU [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σ̂E [m]"] = Konfidenzellipse_ENU["σ̂E [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σ̂N [m]"] = Konfidenzellipse_ENU["σ̂N [m]"].round(6)
|
||||
Konfidenzellipse_ENU["σ̂U [m]"] = Konfidenzellipse_ENU["σ̂U [m]"].round(6)
|
||||
Konfidenzellipse_ENU["Halbachse a_k [m]"] = Konfidenzellipse_ENU["Halbachse a_k [m]"].round(4)
|
||||
Konfidenzellipse_ENU["Halbachse b_k [m]"] = Konfidenzellipse_ENU["Halbachse b_k [m]"].round(4)
|
||||
Konfidenzellipse_ENU["Halbachse c_k [m]"] = Konfidenzellipse_ENU["Halbachse c_k [m]"].round(4)
|
||||
@@ -390,15 +398,7 @@ class Plot:
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def netzplot_ellipsen(
|
||||
Koord_ENU,
|
||||
unbekannten_labels,
|
||||
beobachtungs_labels,
|
||||
df_konf_ellipsen_enu,
|
||||
skalierung,
|
||||
n_ellipse_pts=60,
|
||||
titel="Netzplot im ENU-System mit Konfidenzellipsen"
|
||||
):
|
||||
def netzplot_ellipsen(Koord_ENU: dict[str, tuple[float, float, float]], unbekannten_labels: list, beobachtungs_labels: list, df_konf_ellipsen_enu: pd.DataFrame, skalierung: float, n_ellipse_pts: int = 60, titel: str = "Netzplot im ENU-System mit Konfidenzellipsen") -> go.Figure:
|
||||
|
||||
"""
|
||||
Erstellt einen Netzplot im ENU-System inklusive Konfidenzellipsen, Netzpunkten und Beobachtungslinien.
|
||||
@@ -430,7 +430,6 @@ class Plot:
|
||||
:type titel: str
|
||||
:return: Plotly-Figure-Objekt mit Netz, Beobachtungen und Ellipsen.
|
||||
:rtype: plotly.graph_objects.Figure
|
||||
:raises ValueError: Wenn weder "θ_EN [gon]" noch "θ [gon]" im DataFrame vorhanden ist.
|
||||
"""
|
||||
|
||||
namen = [str(s).strip() for s in unbekannten_labels]
|
||||
@@ -546,7 +545,7 @@ class Plot:
|
||||
return plot
|
||||
|
||||
|
||||
def plot_speichere_aktuelle_ansicht(plot, dateiname=r"Netzqualitaet\netzplot_ellipsen_zoom_ansicht.png"):
|
||||
def plot_speichere_aktuelle_ansicht(plot: go.Figure, dateiname: str = r"Netzqualitaet\netzplot_ellipsen_zoom_ansicht.png") -> None:
|
||||
"""
|
||||
Speichert die aktuell dargestellte Plot-Ansicht als Bilddatei.
|
||||
|
||||
@@ -564,7 +563,6 @@ class Plot:
|
||||
:type dateiname: str
|
||||
:return: None
|
||||
:rtype: None
|
||||
:raises OSError: Wenn die Bilddatei nicht geschrieben werden kann (z.B. fehlender Pfad oder fehlendes Kaleido).
|
||||
"""
|
||||
|
||||
aktuelles_layout = plot.layout
|
||||
|
||||
Reference in New Issue
Block a user