Matplotlib: Füllen des Diagrammbereichs ohne Datenpunktlinien

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Matthias0911
User
Beiträge: 10
Registriert: Montag 4. September 2023, 12:18

Hallo Zusammen,

Ich werte ein CSV-File aus und lasse mir damit mit matplotlib ein Diagramm erstellen.
Wenn ich nun aber die Fläche unter den Datenbank farblich fülle, dann zeichnet er mir für jeden Datenpunkt eine vertikale Linie.

Beispiel: <irgenwie kann man hier keine Bilder hochladen :-(>

Der entsprechende Quellcode des Diagrams sieht so aus:

Code: Alles auswählen

           
                plt.fill_between(strategy_data.index.get_level_values('Closed')[i:i + 2], strategy_data.iloc[i:i + 2], color=fill_color, alpha=0.9, zorder=5)
Hat jemand eine Idee, warum die Linien unter jedem Datenpunkt gezeichnet werden?

Hier gesamte Code der Funktion:

Code: Alles auswählen

# Diese Funktion erstellt die Flächenliniendiagramme und berechnet die benötigten Werte
def create_plots_and_aggregate_data(df_sorted):
    # Gruppieren nach Strategy und Closed, und den kumulierten CashflowInEUR berechnen
    df_grouped = df_sorted.groupby(['Strategy', 'Closed'])['CashflowInEUR'].sum().groupby('Strategy').cumsum()

    # Plot für jede Strategie erstellen
    strategy_plots = {}
    strategies = df_sorted['Strategy'].unique()

    for strategy in strategies:
        if strategy and not pd.isna(strategy):  # Prüfen, ob die Strategie nicht leer und nicht "nan" ist
            # Ändere die Indexierung, um sicherzustellen, dass sie mit dem DataFrame übereinstimmt
            strategy_data = df_grouped[df_grouped.index.get_level_values('Strategy') == strategy]
            print("*********"+strategy+"*********")
            # Überprüfen, ob strategy_data leer ist
            if strategy_data.empty:
                print(f"No data for strategy: {strategy}")
                continue  # Weiter zur nächsten Strategie
            # Größe des Diagrams
            fig, ax = plt.subplots(figsize=(1920 / plt.gcf().dpi, 1080 / plt.gcf().dpi), dpi=plt.gcf().dpi)

            # Grid - horizontale Linien
            ax.grid(which="major", axis='y', color='#dedfe0',alpha=0.4, zorder=1)

            # Debug Info
            print(strategy_data.index.get_level_values('Closed')),

            # Achsenbeschriftung mit Monatsbasis
            # Plot mit Monatsbasis
            plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=1))  # Alle Monate anzeigen
            plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))  # Format der Monatsbezeichnungen

            # Niedrigster und höchster Wert in der Datenreihe
            lowest_value = strategy_data.min()
            highest_value = strategy_data.max()

            # Horizontale gestrichelte Linie bei y = 0, nur wenn negative Werte vorhanden sind
            if lowest_value < 0:
                plt.axhline(0, color='black', linestyle='--', linewidth=0.2, dashes=(40, 50))

            # Schleife durch die Datenpunkte und Farben anpassen
            for i in range(len(strategy_data) - 1):
                value = strategy_data.iloc[i]
                # Den vorherigen Wert zu value hinzufügen
                if value < 0:
                    line_color = '#8B0000'
                    fill_color = '#FF6347'  # Farbe für den Bereich unter der Linie
                else:
                    line_color = '#000080'
                    fill_color = '#6495ed'  # Farbe für den Bereich unter der Linie

                # Linie zeichnen
                plt.plot(strategy_data.index.get_level_values('Closed')[i:i + 2], strategy_data.iloc[i:i + 2],alpha=0.5, color=line_color, linewidth=1.5, zorder=6)

                # Bereich unter der Linie füllen
                plt.fill_between(strategy_data.index.get_level_values('Closed')[i:i + 2], strategy_data.iloc[i:i + 2], color=fill_color, alpha=0.9, zorder=5)

                # Marker zeichnen ohne Linien
                plt.scatter(strategy_data.index.get_level_values('Closed')[i:i + 2], strategy_data.iloc[i:i + 2], c='#303537', marker='o', s=10, edgecolors='none')

            # Beschriftung letzter Wert

            # Den kumulierten CashflowInEUR für den letzten Datenpunkt dieser Strategie erhalten
            last_closed_value = strategy_data.index.get_level_values('Closed').values[-1]
            last_closed_cumulative_cashflow = df_grouped.loc[strategy, last_closed_value]

            print("-------------------Last Closed Values")
            print(strategy_data.index.get_level_values('Closed').values[-1])
            print(df_grouped.loc[strategy, last_closed_value])
            print("-------------------Last Closed Values")

            # Beschriftung des letzten Datenpunkts auf der x-Achse mit Euro-Symbol und dem kumulierten Cashflow
            plt.annotate(f'€ {round(last_closed_cumulative_cashflow, 0):,.0f}', (last_closed_value, strategy_data.iloc[-1]), textcoords="offset points", xytext=(5, -2), ha='left', fontsize=9)
            # Beschriftung letzter Wert

            ###  Add a red line and rectangle on top
            ax.plot([0.08, 0.95], [0.98, 0.98], transform=fig.transFigure, clip_on=False, color='#E3120B',linewidth=1.5)
            ax.add_patch(plt.Rectangle((0.08, 0.98), 0.05, -0.02, facecolor='#E3120B', transform=fig.transFigure, clip_on=False, linewidth=0))

            # Anzahl der Trades
            num_trades = len(strategy_data)
            # Hinzufügen der Werte (mean, min, max) im Diagramm
            agg_values = df_sorted[df_sorted['Strategy'] == strategy].agg({
                'CashflowInEUR': ['mean', 'min', 'max'],
                'DaysInTrade': ['mean', 'min', 'max']
            })

            # Add a title and subtitle
            ax.text(x=0.08, y=0.935, s=f'Entwicklung der Strategie: {strategy}', transform=fig.transFigure, ha='left', fontsize=18, weight='bold', alpha=0.8)
            ax.text(x=0.08, y=0.915, s=f"Anzahl der Trades: {num_trades} // "
                                       f"Durchschnittsertrag pro Trade: € {agg_values['CashflowInEUR']['mean']:.2f} // "
                                       f"Schlechtester Trade: € {agg_values['CashflowInEUR']['min']:.2f} // "
                                       f"Bester Trade: € {agg_values['CashflowInEUR']['max']:.2f} // "
                                       f"Endergebnis: € {last_closed_cumulative_cashflow:.2f} "
                    , transform=fig.transFigure, ha='left', fontsize=11, alpha=0.8)

            #Beschriftung
            plt.ylabel('Kumulierter Ertrag in Euro')
            # Überprüfen, ob die Legende vorhanden ist, bevor wir sie entfernen
            if ax.get_legend():
                ax.get_legend().remove()

            # Bereinigen des Funktionsnamens, um unzulässige Zeichen zu entfernen
            strategy_name = re.sub(r'[\\/*?:"<>|]', '', strategy)
            # Bild als Datei speichern
            img_filename = os.path.join('tmp', f"strategie_{strategy_name}.png")
            plt.savefig(img_filename, format='png')
            plt.close()

            # Hier wird der <a> Tag um das Bild herum platziert
            strategy_plots[strategy] = f'<div class="container"><a target="_blank" href="{img_filename}"><img width="75%" src="{img_filename}" alt="Strategie {strategy}"></a></div>'

    return strategy_plots
Antworten