microsoft/qlib · error · ValueError

df is empty.

Error message

df is empty.

What it means

BaseGraph._init_data (qlib/contrib/report/graph.py) refuses to build a plotly graph from an empty DataFrame. The constructor stores the df, and _init_data immediately raises ValueError('df is empty.') when df.empty is True, because there is nothing to plot and downstream slicing would silently produce blank figures.

Source

Thrown at qlib/contrib/report/graph.py:52

        """
        self._df = df

        self._layout = dict() if layout is None else layout
        self._graph_kwargs = dict() if graph_kwargs is None else graph_kwargs
        self._name_dict = name_dict

        self.data = None

        self._init_parameters(**kwargs)
        self._init_data()

    def _init_data(self):
        """

        :return:
        """
        if self._df.empty:
            raise ValueError("df is empty.")

        self.data = self._get_data()

    def _init_parameters(self, **kwargs):
        """

        :param kwargs
        """

        # Instantiate graphics parameters
        self._graph_type = self._name.lower().capitalize()

        # Displayed column name
        if self._name_dict is None:
            self._name_dict = {_item: _item for _item in self._df.columns}

    @staticmethod
    def get_instance_with_graph_parameters(graph_type: str = None, **kwargs):

View on GitHub (pinned to 79633dd950)

Solutions

  1. Inspect why the DataFrame is empty: check the upstream query (recorder.load_pred, analysis result, date range, instrument filter)
  2. Widen or correct the date/instrument selection so at least one row matches
  3. Guard at the call site: skip plotting when df.empty instead of constructing the graph
  4. If predictions are missing, run signal recording (SignalRecord) before generating report graphs

Example fix

# before
graph = ScatterGraph(df=result_df)

# after
if result_df.empty:
    logger.warning('no data to plot; skip')
else:
    graph = ScatterGraph(df=result_df)
Defensive patterns

Strategy: validation

Validate before calling

if df is None or df.empty:
    raise ValueError(f'cannot build graph: df has {0 if df is None else len(df)} rows')
graph = ScatterGraph(df=df)

Type guard

def has_plot_data(df: pd.DataFrame) -> bool:
    return df is not None and not df.empty and len(df.columns) > 0

Try / catch

try:
    graph = ScatterGraph(df=df)
except ValueError as e:
    if 'empty' in str(e):
        logger.warning('skipping plot: input dataframe empty')
    else:
        raise

Prevention

When it happens

Trigger: Passing an empty pd.DataFrame (zero rows or zero columns) as the df kwarg to any BaseGraph subclass (e.g. ScatterGraph, BarGraph) or to a graph built via BaseGraph.get_instance_with_graph_parameters with df=empty_df.

Common situations: Feeding the graph a recorder's prediction/analysis output that came back empty (e.g. no predictions were saved for the segment); filtering a report DataFrame by date/instrument conditions that match nothing; upstream data preparation silently returning an empty frame.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/8655825f3cf32812. Report an issue: GitHub.