Promotion: Verbesserung der Visualiserungen und Exportfunktionen in der Systematischen Literaturrecherche; Fehlerbehebung
This commit is contained in:
@ -6,6 +6,7 @@ from ci_template.plotly_template import export_figure
|
|||||||
from config_korrelation import (
|
from config_korrelation import (
|
||||||
theme,
|
theme,
|
||||||
export_fig_visual,
|
export_fig_visual,
|
||||||
|
export_fig_png,
|
||||||
export_fig_clusteranalyse,
|
export_fig_clusteranalyse,
|
||||||
export_fig_correlation_suchbegriffe_kategorien,
|
export_fig_correlation_suchbegriffe_kategorien,
|
||||||
export_fig_correlation_fu_kategorien,
|
export_fig_correlation_fu_kategorien,
|
||||||
@ -61,6 +62,7 @@ def prepare_figure_export(fig, name):
|
|||||||
|
|
||||||
def export_and_transfer_figure(fig, function_name, export_flag):
|
def export_and_transfer_figure(fig, function_name, export_flag):
|
||||||
export_figure(fig, function_name, export_flag, export_fig_png)
|
export_figure(fig, function_name, export_flag, export_fig_png)
|
||||||
|
fig.show()
|
||||||
|
|
||||||
# BibTeX-Datei laden
|
# BibTeX-Datei laden
|
||||||
bib_path = os.path.join("Research", "Charité - Universitätsmedizin Berlin", "Systematische Literaturrecherche", "Bibliothek", bib_filename)
|
bib_path = os.path.join("Research", "Charité - Universitätsmedizin Berlin", "Systematische Literaturrecherche", "Bibliothek", bib_filename)
|
||||||
@ -436,7 +438,6 @@ def visualize_indizes_vs_indizes(export_flag):
|
|||||||
export_flag
|
export_flag
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#======================================
|
#======================================
|
||||||
|
|
||||||
cluster_colors = {
|
cluster_colors = {
|
||||||
@ -723,3 +724,7 @@ visualize_suchbegriffe_vs_suchbegriffe(export_flag=export_fig_correlation_suchbe
|
|||||||
visualize_kategorien_vs_kategorien(export_flag=export_fig_correlation_kategorien_kategorien)
|
visualize_kategorien_vs_kategorien(export_flag=export_fig_correlation_kategorien_kategorien)
|
||||||
visualize_indizes_vs_indizes(export_flag=export_fig_correlation_indizes_indizes)
|
visualize_indizes_vs_indizes(export_flag=export_fig_correlation_indizes_indizes)
|
||||||
plot_average_correlation_plotly(summary_df)
|
plot_average_correlation_plotly(summary_df)
|
||||||
|
|
||||||
|
# Visualisierungsoption für Plotly: Immer im Browser öffnen
|
||||||
|
import plotly.io as pio
|
||||||
|
pio.renderers.default = 'browser'
|
||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
from config_netzwerk import theme, export_fig_visual, bib_filename
|
from config_netzwerk import theme, export_fig_visual, bib_filename
|
||||||
|
|
||||||
from ci_template.plotly_template import export_figure
|
from ci_template.plotly_template import export_figure as export_figure_ci
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -63,8 +63,10 @@ from config_netzwerk import (
|
|||||||
export_fig_visualize_languages,
|
export_fig_visualize_languages,
|
||||||
)
|
)
|
||||||
|
|
||||||
def export_figure(fig, name, flag, bib_filename=None):
|
from config_netzwerk import export_fig_png
|
||||||
export_figure(fig, name, flag, export_fig_png)
|
|
||||||
|
def export_figure_local(fig, name, flag, bib_filename=None):
|
||||||
|
export_figure_ci(fig, name, flag, export_fig_png)
|
||||||
|
|
||||||
from ci_template.plotly_template import get_colors, get_plot_styles, get_standard_layout
|
from ci_template.plotly_template import get_colors, get_plot_styles, get_standard_layout
|
||||||
|
|
||||||
@ -322,7 +324,7 @@ def visualize_network(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
|
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_network", export_fig_visualize_network, bib_filename)
|
export_figure_local(fig, "visualize_network", export_fig_visualize_network, bib_filename)
|
||||||
|
|
||||||
# Einfache Pfadanalyse nach dem Anzeigen der Figur
|
# Einfache Pfadanalyse nach dem Anzeigen der Figur
|
||||||
if 'e-learning' in G and 'online:lernen' in G:
|
if 'e-learning' in G and 'online:lernen' in G:
|
||||||
@ -429,7 +431,7 @@ def visualize_tags(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
|
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_tags", export_fig_visualize_tags, bib_filename)
|
export_figure_local(fig, "visualize_tags", export_fig_visualize_tags, bib_filename)
|
||||||
|
|
||||||
# Visualisierung 3: Häufigkeit Index
|
# Visualisierung 3: Häufigkeit Index
|
||||||
def visualize_index(bib_database):
|
def visualize_index(bib_database):
|
||||||
@ -477,7 +479,7 @@ def visualize_index(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_index", export_fig_visualize_index, bib_filename)
|
export_figure_local(fig, "visualize_index", export_fig_visualize_index, bib_filename)
|
||||||
|
|
||||||
# Visualisierung 4: Häufigkeit Forschungsunterfragen
|
# Visualisierung 4: Häufigkeit Forschungsunterfragen
|
||||||
def visualize_research_questions(bib_database):
|
def visualize_research_questions(bib_database):
|
||||||
@ -526,7 +528,7 @@ def visualize_research_questions(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_research_questions", export_fig_visualize_research_questions, bib_filename)
|
export_figure_local(fig, "visualize_research_questions", export_fig_visualize_research_questions, bib_filename)
|
||||||
|
|
||||||
# Visualisierung 5: Häufigkeit spezifischer Kategorien
|
# Visualisierung 5: Häufigkeit spezifischer Kategorien
|
||||||
def visualize_categories(bib_database):
|
def visualize_categories(bib_database):
|
||||||
@ -570,7 +572,7 @@ def visualize_categories(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_categories", export_fig_visualize_categories, bib_filename)
|
export_figure_local(fig, "visualize_categories", export_fig_visualize_categories, bib_filename)
|
||||||
|
|
||||||
# Zeitreihenanalyse der Veröffentlichungen
|
# Zeitreihenanalyse der Veröffentlichungen
|
||||||
def visualize_time_series(bib_database):
|
def visualize_time_series(bib_database):
|
||||||
@ -617,7 +619,7 @@ def visualize_time_series(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.update_traces(line=plot_styles['linie_primaryLine'])
|
fig.update_traces(line=plot_styles['linie_primaryLine'])
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_time_series", export_fig_visualize_time_series, bib_filename)
|
export_figure_local(fig, "visualize_time_series", export_fig_visualize_time_series, bib_filename)
|
||||||
else:
|
else:
|
||||||
print("Keine gültigen Veröffentlichungsjahre gefunden.")
|
print("Keine gültigen Veröffentlichungsjahre gefunden.")
|
||||||
|
|
||||||
@ -651,7 +653,7 @@ def visualize_top_authors(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_top_authors", export_fig_visualize_top_authors, bib_filename)
|
export_figure_local(fig, "visualize_top_authors", export_fig_visualize_top_authors, bib_filename)
|
||||||
else:
|
else:
|
||||||
print("Keine Autoren gefunden.")
|
print("Keine Autoren gefunden.")
|
||||||
|
|
||||||
@ -697,7 +699,7 @@ def visualize_top_publications(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
fig.update_traces(marker=plot_styles['balken_primaryLine'])
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_top_publications", export_fig_visualize_top_publications, bib_filename)
|
export_figure_local(fig, "visualize_top_publications", export_fig_visualize_top_publications, bib_filename)
|
||||||
|
|
||||||
##########
|
##########
|
||||||
|
|
||||||
@ -829,7 +831,7 @@ def create_path_diagram(data):
|
|||||||
layout["autosize"] = True
|
layout["autosize"] = True
|
||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "create_path_diagram", export_fig_create_path_diagram, bib_filename)
|
export_figure_local(fig, "create_path_diagram", export_fig_create_path_diagram, bib_filename)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
|
||||||
@ -962,7 +964,7 @@ def create_sankey_diagram(bib_database):
|
|||||||
layout["autosize"] = True
|
layout["autosize"] = True
|
||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "create_sankey_diagram", export_fig_create_sankey_diagram, bib_filename)
|
export_figure_local(fig, "create_sankey_diagram", export_fig_create_sankey_diagram, bib_filename)
|
||||||
|
|
||||||
##########
|
##########
|
||||||
|
|
||||||
@ -1090,7 +1092,7 @@ def visualize_sources_status(bib_database):
|
|||||||
layout["autosize"] = True
|
layout["autosize"] = True
|
||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
export_figure(fig, "visualize_sources_status", export_fig_visualize_sources_status, bib_filename)
|
export_figure_local(fig, "visualize_sources_status", export_fig_visualize_sources_status, bib_filename)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
|
||||||
@ -1195,7 +1197,7 @@ def visualize_languages(bib_database):
|
|||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
# Tabelle ausgeben
|
# Tabelle ausgeben
|
||||||
print(tabulate(df.sort_values("Anzahl", ascending=False), headers="keys", tablefmt="grid", showindex=False))
|
print(tabulate(df.sort_values("Anzahl", ascending=False), headers="keys", tablefmt="grid", showindex=False))
|
||||||
export_figure(fig, "visualize_languages", export_fig_visualize_languages, bib_filename)
|
export_figure_local(fig, "visualize_languages", export_fig_visualize_languages, bib_filename)
|
||||||
|
|
||||||
# Visualisierung der Verteilung von ENTRYTYPE innerhalb jeder Sprache
|
# Visualisierung der Verteilung von ENTRYTYPE innerhalb jeder Sprache
|
||||||
def visualize_language_entrytypes(bib_database):
|
def visualize_language_entrytypes(bib_database):
|
||||||
@ -1297,7 +1299,7 @@ def visualize_language_entrytypes(bib_database):
|
|||||||
fig.update_layout(**layout)
|
fig.update_layout(**layout)
|
||||||
fig.show(config={"responsive": True})
|
fig.show(config={"responsive": True})
|
||||||
print(tabulate(grouped.sort_values(["Sprache", "Eintragstyp"]), headers=["Sprache", "Eintragstyp", "Anzahl", "Anteil innerhalb Sprache (%)", "Typgruppe"], tablefmt="grid", showindex=False))
|
print(tabulate(grouped.sort_values(["Sprache", "Eintragstyp"]), headers=["Sprache", "Eintragstyp", "Anzahl", "Anteil innerhalb Sprache (%)", "Typgruppe"], tablefmt="grid", showindex=False))
|
||||||
export_figure(fig, "visualize_language_entrytypes", export_fig_visualize_languages, bib_filename)
|
export_figure_local(fig, "visualize_language_entrytypes", export_fig_visualize_languages, bib_filename)
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import matplotlib.pyplot as plt
|
|||||||
import plotly.graph_objects as go
|
import plotly.graph_objects as go
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from scipy.stats.mstats import winsorize
|
from scipy.stats.mstats import winsorize
|
||||||
|
from scipy.stats import iqr
|
||||||
|
|
||||||
# --- CI-Template & Konfiguration ---
|
# --- CI-Template & Konfiguration ---
|
||||||
from ci_template.plotly_template import (
|
from ci_template.plotly_template import (
|
||||||
@ -18,6 +19,7 @@ from ci_template.plotly_template import (
|
|||||||
)
|
)
|
||||||
from ci_template.plotly_template import export_figure
|
from ci_template.plotly_template import export_figure
|
||||||
from config_deskriptive_literaturauswahl import theme, export_fig_visual
|
from config_deskriptive_literaturauswahl import theme, export_fig_visual
|
||||||
|
from config_deskriptive_literaturauswahl import export_fig_png, export_fig_silhouette_plot
|
||||||
|
|
||||||
# --- Initialisierung ---
|
# --- Initialisierung ---
|
||||||
os.system('cls' if os.name == 'nt' else 'clear')
|
os.system('cls' if os.name == 'nt' else 'clear')
|
||||||
@ -40,65 +42,110 @@ n_values = np.array([
|
|||||||
])
|
])
|
||||||
|
|
||||||
# --- Berechnungen ---
|
# --- Berechnungen ---
|
||||||
q1 = np.percentile(sc_values, 25)
|
# Berechne IQR und automatische untere/obere Grenzen
|
||||||
q2 = np.percentile(sc_values, 50)
|
sc_iqr = iqr(sc_values)
|
||||||
q3 = np.percentile(sc_values, 75)
|
q1_val = np.percentile(sc_values, 25)
|
||||||
|
q3_val = np.percentile(sc_values, 75)
|
||||||
|
lower_bound = q1_val - 1.5 * sc_iqr
|
||||||
|
upper_bound = q3_val + 1.5 * sc_iqr
|
||||||
|
sc_winsorized = np.clip(sc_values, lower_bound, upper_bound)
|
||||||
|
median_winsorized = np.median(sc_winsorized)
|
||||||
|
|
||||||
|
# Quartile
|
||||||
|
q1 = q1_val
|
||||||
|
q2 = np.median(sc_values)
|
||||||
|
q3 = q3_val
|
||||||
max_value = np.max(sc_values)
|
max_value = np.max(sc_values)
|
||||||
min_value = np.min(sc_values)
|
min_value = np.min(sc_values)
|
||||||
|
|
||||||
sc_winsorized = winsorize(sc_values, limits=[0.1, 0.1])
|
# Schwellenwerte datenbasiert
|
||||||
median_winsorized = np.median(sc_winsorized)
|
fatigue_threshold = q1 # oder eine alternative datenbasierte Schwelle
|
||||||
|
circadian_optimum = q3 # oder np.percentile(sc_values, 90)
|
||||||
fatigue_threshold = 0.96
|
|
||||||
circadian_optimum = 0.99
|
|
||||||
|
|
||||||
# --- Visualisierung ---
|
# --- Visualisierung ---
|
||||||
fig = go.Figure()
|
fig = go.Figure()
|
||||||
|
|
||||||
# SC-Linie
|
from ci_template.plotly_template import get_plot_styles
|
||||||
fig.add_trace(go.Scatter(x=years, y=sc_values, name='Silhouette-Scores',
|
styles = get_plot_styles()
|
||||||
mode='lines+markers', yaxis='y1'))
|
|
||||||
|
|
||||||
# n-Balken
|
fig.add_trace(go.Scatter(
|
||||||
fig.add_trace(go.Bar(x=years, y=n_values, name='n-Werte (Fallzahlen)',
|
x=years,
|
||||||
yaxis='y2', opacity=0.3, marker_color=colors["depthArea"]))
|
y=n_values,
|
||||||
|
name='Fallzahlen (n)',
|
||||||
|
yaxis='y2',
|
||||||
|
mode='lines+markers',
|
||||||
|
line=dict(color=colors["secondaryLine"], width=1),
|
||||||
|
marker=dict(size=16, color=colors["secondaryLine"], symbol="square"),
|
||||||
|
showlegend=True
|
||||||
|
))
|
||||||
|
|
||||||
# Quartile & Bezugslinien
|
# Quartile & Bezugslinien
|
||||||
fig.add_trace(go.Scatter(x=years, y=[q1]*len(years), mode='lines', name=f'SC Q1 = {q1:.4f}',
|
fig.add_trace(go.Scatter(x=years, y=[q1]*len(years), mode='lines', name='SC Q1',
|
||||||
line=dict(dash='dot', color='green'), yaxis='y1'))
|
line=dict(dash='dot', color=colors["brightArea"]), yaxis='y1'))
|
||||||
fig.add_trace(go.Scatter(x=years, y=[q2]*len(years), mode='lines', name=f'SC Median (Q2) = {q2:.4f}',
|
fig.add_trace(go.Scatter(x=years, y=[q2]*len(years), mode='lines', name='SC Median (Q2)',
|
||||||
line=dict(dash='dot', color='blue'), yaxis='y1'))
|
line=dict(dash='dot', color=colors["depthArea"]), yaxis='y1'))
|
||||||
fig.add_trace(go.Scatter(x=years, y=[q3]*len(years), mode='lines', name=f'SC Q3 = {q3:.4f}',
|
fig.add_trace(go.Scatter(x=years, y=[q3]*len(years), mode='lines', name='SC Q3',
|
||||||
line=dict(dash='dot', color='purple'), yaxis='y1'))
|
line=dict(dash='dot', color=colors["accent"]), yaxis='y1'))
|
||||||
fig.add_trace(go.Scatter(x=years, y=[min_value]*len(years), mode='lines', name=f'SC Min = {min_value:.4f}',
|
fig.add_trace(go.Scatter(
|
||||||
line=dict(dash='dash', color='red'), yaxis='y1'))
|
x=years,
|
||||||
fig.add_trace(go.Scatter(x=years, y=[max_value]*len(years), mode='lines', name=f'SC Max = {max_value:.4f}',
|
y=[min_value]*len(years),
|
||||||
line=dict(dash='dash', color='orange'), yaxis='y1'))
|
mode='lines',
|
||||||
fig.add_trace(go.Scatter(x=years, y=[fatigue_threshold]*len(years), mode='lines',
|
name='SC Min',
|
||||||
name=f'Schwelle: Erschöpfungs-Bias = {fatigue_threshold:.4f}',
|
line=dict(dash='dash', color=colors["negativeHighlight"]),
|
||||||
line=dict(dash='dashdot', color='firebrick'), yaxis='y1'))
|
yaxis='y1'
|
||||||
fig.add_trace(go.Scatter(x=years, y=[circadian_optimum]*len(years), mode='lines',
|
))
|
||||||
name=f'Idealer Wert (circadian) = {circadian_optimum:.4f}',
|
fig.add_trace(go.Scatter(
|
||||||
line=dict(dash='dashdot', color='darkcyan'), yaxis='y1'))
|
x=years,
|
||||||
fig.add_trace(go.Scatter(x=years, y=[median_winsorized]*len(years), mode='lines',
|
y=[max_value]*len(years),
|
||||||
name=f'Winsorisierter Median = {median_winsorized:.4f}',
|
mode='lines',
|
||||||
line=dict(dash='dot', color='black'), yaxis='y1'))
|
name='SC Max',
|
||||||
|
line=dict(dash='dash', color=colors["positiveHighlight"]),
|
||||||
|
yaxis='y1'
|
||||||
|
))
|
||||||
|
|
||||||
|
fig.add_trace(go.Scatter(
|
||||||
|
x=years,
|
||||||
|
y=sc_values,
|
||||||
|
name='Silhouette-Scores',
|
||||||
|
yaxis='y1',
|
||||||
|
mode='lines+markers',
|
||||||
|
line=dict(color=colors["primaryLine"], width=1),
|
||||||
|
marker=dict(size=16, color=colors["primaryLine"], symbol="circle"),
|
||||||
|
showlegend=True
|
||||||
|
))
|
||||||
|
|
||||||
# Layout
|
# Layout
|
||||||
fig.update_layout(
|
layout = get_standard_layout(
|
||||||
**get_standard_layout(
|
title="Silhouette-Scores und Fallzahlen pro Jahr",
|
||||||
title=f"Silhouette-Scores und Fallzahlen (n={sum(n_values)}, Stand: {current_date})",
|
x_title='Jahr',
|
||||||
x_title="Jahr",
|
y_title='Silhouette-Score',
|
||||||
y_title="Silhouette-Score",
|
yaxis2=dict(
|
||||||
yaxis2=dict(
|
title="Fallzahlen (n)",
|
||||||
title="Fallzahlen (n)",
|
showgrid=False,
|
||||||
showgrid=False
|
title_standoff=20
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
layout["font"] = {"size": 14, "color": colors['text']}
|
||||||
# Anzeige
|
layout["title"] = dict(text="Silhouette-Scores und Fallzahlen pro Jahr", font=dict(color=colors["text"]))
|
||||||
fig.show(config={"responsive": True})
|
layout["margin"] = dict(b=80, t=120, l=60, r=60)
|
||||||
|
layout["xaxis"] = layout.get("xaxis", {})
|
||||||
|
layout["xaxis"]["automargin"] = True
|
||||||
|
layout["autosize"] = True
|
||||||
|
layout["legend"] = dict(
|
||||||
|
x=1.05,
|
||||||
|
y=1.0,
|
||||||
|
xanchor="left",
|
||||||
|
yanchor="top",
|
||||||
|
orientation="v",
|
||||||
|
traceorder="normal",
|
||||||
|
itemclick="toggleothers",
|
||||||
|
itemdoubleclick="toggle"
|
||||||
|
)
|
||||||
|
fig.update_layout(**layout)
|
||||||
|
|
||||||
# --- Export ---
|
# --- Export ---
|
||||||
export_figure(fig, "silhouette_scores_und_fallzahlen", export_fig_silhouette_plot, export_fig_png)
|
export_figure(fig, "silhouette_scores_und_fallzahlen", export_fig_silhouette_plot, export_fig_png)
|
||||||
|
|
||||||
|
# (Hinweis: Balkenfarbe wird direkt im Bar-Trace gesetzt)
|
||||||
|
|
||||||
|
fig.show(config={"responsive": True})
|
||||||
|
|||||||
Reference in New Issue
Block a user