plotly / plotly/plotly.py

[FEATURE]: Make Plotly Express dataframe implementation-agnostic

Offen
#5,667 6 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

enhancement feature P2 size: 3
Vorherrschende Sprache
Python
Sterne
18.8k
Forks
2.8k
Ø Merge
16 Std. 26 Min.
Gemergte PRs (30 T.)
21

Beschreibung

[FEATURE]: Make Plotly Express dataframe implementation-agnostic

Description

For a long time, there's been questions around how tightly Plotly Express depends on pandas. For example, here's a program from the Getting Started page that's supposed to show how easy it is to make a simple plot with Plotly Express:

import plotly.express as px

fig = px.bar(x=["a", "b", "c"], y=[1, 3, 2])
fig.show()

But if you run this with only plotly[express] installed, you get an error stating that pandas is required:

Traceback (most recent call last):
  File "/.../plotly/express/_core.py", line 1210, in to_named_series
    import pandas as pd
ModuleNotFoundError: No module named 'pandas'
...
NotImplementedError: Pandas installation is required if no dataframe is provided.

I think I understand this error; Plotly doesn't want to require pandas, when there are other dataframe-based libraries that people are choosing such as Polars. However, this message appears even if you have Polars installed. I think we can make Plotly Express more agnostic toward dataframe providers by looking for an available provider, rather than exiting if pandas is not found.

Why should this feature be added?

Plotly claims to not require pandas, but it still requires pandas in places where other dataframe implementations seem to work.

Mocks/ designs

I made some small changes to plotly/express/_core.py, which allows the above example to work with Polars installed. First, add a new function to look for an existing library that supports dataframes through narwhals:

def get_df_implementation():
    """Get an installed dataframe implementation."""
    for df_implementation in ("pandas", "polars"):
        try:
            return import_module(df_implementation)
        except ImportError:
            pass

    msg = (
        "A dataframe implementation such as Pandas or Polars is required if "
        "no dataframe is provided."
    )
    raise NotImplementedError(msg)

This POC version looks for pandas first, and then Polars.

The only change in the function to_named_series() is to call get_df_implemenation() in the else block, instead of doing its own check for pandas:

def to_named_series(x, name=None, native_namespace=None):
    ...
    if isinstance(x, nw.Series):
        return x.rename(name)
    elif native_namespace is not None:
        return nw.new_series(name=name, values=x, native_namespace=native_namespace)
    else:
        df_implementation = get_df_implementation()
        return nw.new_series(name=name, values=x, native_namespace=df_implementation)

The existing function process_args_into_dataframe() needs one call to get_df_implemenation() as well:

def process_args_into_dataframe(
    args, wide_mode, var_name, value_name, is_pd_like, native_namespace
):
    ...
    length = len(df_output[next(iter(df_output))]) if len(df_output) else 0

    if native_namespace is None:
        native_namespace = get_df_implementation()

    if ranges:
        import numpy as np
        ...

With these changes, the above example runs without errors when Polars is installed. When pandas and Polars are both unavailable, the error states that one of these libraries must be installed.

Notes

I'm not tied to this particular implementation in any way, this was just a proof of concept to see if we could make Plotly more agnostic about the dataframe provider.

Is this a direction that's worth pursuing? I'm happy to work on a PR if it is, or happy to see others more versed in Plotly's internals implement it.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne in plotly/express/_core.py, indem du to_named_series() und process_args_into_dataframe() liest, und überprüfe anschließend, wie Narwhals den nativen Dataframe-Namespace erhält. Führe das Getting Started-Balkenbeispiel aus, wenn pandas nicht verfügbar und Polars installiert ist, und stelle sicher, dass das Beispiel funktioniert, während die Fehlermeldung bei fehlendem Provider informativ bleibt, wenn keiner der beiden Provider verfügbar ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
pandas, python
Bereich
data-visualization
Issue-Typ
Feature
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
58/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.