Skip to content

Python Pandas: How to Fix TypeError: no numeric data to plot

Learn how to resolve the Pandas TypeError: no numeric data to plot when working with .plot(), including data type conversion and validation techniques for numeric columns.

When attempting to generate plots directly from a Pandas DataFrame using its .plot() method (which often relies on Matplotlib), you might encounter the TypeError: no numeric data to plot. This error indicates that the DataFrame or the specific subset of columns you're trying to plot either contains no data or does not have any columns with numeric data types (like integers or floats) that can be meaningfully plotted.

This guide explains the common causes of this error and provides solutions, primarily focusing on data type conversion and ensuring your DataFrame has plottable numeric data.

Understanding the Error: Plotting Numeric Data

Most standard plotting functions (like line plots, bar plots, scatter plots) require numerical data for their axes and values. When you call DataFrame.plot(), Pandas attempts to find numeric columns to use for the plot. If it cannot find any, or if the DataFrame subset being plotted is empty, it raises the TypeError: no numeric data to plot.

Example Setup:

import pandas as pd
import matplotlib.pyplot as plt # For plt.show()

data = {
    'Year': [2020, 2021, 2022, 2023],
    'Revenue': ['100.5M', '120.2M', '150.7M', '180.0M'],    # Strings
    'Expenses': ['70M', '80M', '95M', '110M'],              # Strings
    'Region': ['North', 'South', 'North', 'West']
}
df_original = pd.DataFrame(data)
print("Original DataFrame:")
print(df_original)
print("Original dtypes:")
print(df_original.dtypes)

Output:

Original DataFrame:
   Year Revenue Expenses Region
0  2020  100.5M      70M  North
1  2021  120.2M      80M  South
2  2022  150.7M      95M  North
3  2023  180.0M     110M   West
Original dtypes:
Year         int64
Revenue     object
Expenses    object
Region      object
dtype: object

Cause 1: Columns Have Non-Numeric Data Types (e.g., 'object'/string)

This is the most common cause. Columns that appear numeric might actually be stored as strings (Pandas dtype object) due to how the data was loaded or created.

The Problem

Attempting to plot columns that Pandas sees as non-numeric.

import pandas as pd
import matplotlib.pyplot as plt # For plt.show()

data = {
    'Year': [2020, 2021, 2022, 2023],
    'Revenue': ['100.5M', '120.2M', '150.7M', '180.0M'],    # Strings
    'Expenses': ['70M', '80M', '95M', '110M'],              # Strings
    'Region': ['North', 'South', 'North', 'West']
}
df_original = pd.DataFrame(data)
df_plot_attempt = df_original.copy()
try:
    df_plot_attempt[['Revenue', 'Expenses']].plot(kind='line')
    plt.title("Financials Over Time (Attempt)")
    plt.show()
except TypeError as e:
    print(f"Caught TypeError: {e}")

Output:

Caught TypeError: no numeric data to plot

The DataFrame.astype() method is used to cast Pandas objects to a specified dtype. You'll need to clean the string data first (e.g., remove 'M') before converting.

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({
    'Year': [2020, 2021, 2022, 2023],
    'Revenue': ['100.5M', '120.2M', '150.7M', '180.0M'],
    'Expenses': ['70M', '80M', '95M', '110M'],
    'Region': ['North', 'South', 'North', 'West']
})
df = df.set_index('Year') # Setting 'Year' as index for a meaningful x-axis

df['Revenue'] = df['Revenue'].str.replace('M', '').astype(float)
df['Expenses'] = df['Expenses'].str.replace('M', '').astype(float)

print("DataFrame after type conversion:")
print(df)
print()

print("Dtypes after conversion:")
print(df.dtypes)
print()

df[['Revenue', 'Expenses']].plot(kind='line', title="Financials (Millions)")
plt.ylabel("Amount (Millions)")
plt.show()

Output:

DataFrame after type conversion:
      Revenue  Expenses Region
Year                          
2020    100.5      70.0  North
2021    120.2      80.0  South
2022    150.7      95.0  North
2023    180.0     110.0   West

Dtypes after conversion:
Revenue     float64
Expenses    float64
Region       object
dtype: object

Solution 2: Convert Columns to Numeric using pd.to_numeric()

pd.to_numeric() is another robust way to convert. It can also handle errors (e.g., by converting non-numeric values to NaN).

import pandas as pd
import matplotlib.pyplot as plt

df_tonumeric = pd.DataFrame({
    'Year': [2020, 2021, 2022, 2023],
    'Revenue': ['100.5M', '120.2M', 'Not Available', '180.0M'], # Added a non-numeric string
    'Expenses': ['70M', '80M', '95M', '110M'],
    'Region': ['North', 'South', 'North', 'West']
})
df_tonumeric = df_tonumeric.set_index('Year')

df_tonumeric['Revenue'] = pd.to_numeric(df_tonumeric['Revenue'].str.replace('M', ''), errors='coerce')
df_tonumeric['Expenses'] = pd.to_numeric(df_tonumeric['Expenses'].str.replace('M', ''), errors='coerce')

print("DataFrame after pd.to_numeric conversion:")
print(df_tonumeric)
print()

print("Dtypes after pd.to_numeric:")
print(df_tonumeric.dtypes)
print()

df_tonumeric[['Revenue', 'Expenses']].plot(kind='bar', title="Financials (Millions) - with to_numeric")
plt.ylabel("Amount (Millions)")
plt.show()

Output:

DataFrame after pd.to_numeric conversion:
      Revenue  Expenses Region
Year                          
2020    100.5        70  North
2021    120.2        80  South
2022      NaN        95  North
2023    180.0       110   West

Dtypes after pd.to_numeric:
Revenue     float64
Expenses      int64
Region       object
dtype: object

Verifying Data Types with DataFrame.dtypes

Always check the dtypes of your columns before plotting if you suspect this error.

print(df.dtypes)

Cause 2: DataFrame or Selected Subset is Empty

If the DataFrame you're trying to plot, or the subset of columns selected for plotting, is empty, there's no data to visualize.

The Problem

import pandas as pd
import matplotlib.pyplot as plt

df_empty = pd.DataFrame() # An empty DataFrame

try:
    df_empty.plot()
    plt.show()
except TypeError as e:
    print(f"Error plotting empty DataFrame: {e}")

df_non_numeric_cols_only = pd.DataFrame({'Category': ['A', 'B'], 'Region': ['X', 'Y']})
try:
    df_non_numeric_cols_only.plot()
    plt.show()
except TypeError as e:
    print(f"Error plotting DataFrame with only non-numeric columns: {e}")

Output:

Error plotting empty DataFrame: no numeric data to plot
Error plotting DataFrame with only non-numeric columns: no numeric data to plot

Solution: Ensure Data is Present

Before plotting, verify that your DataFrame (or the slice you're plotting) is not empty and contains at least one numeric column.

import pandas as pd
import matplotlib.pyplot as plt

df_with_data = pd.DataFrame({'Values': [10, 20, 15, 25]})
df_empty_check = pd.DataFrame()

if not df_with_data.empty and any(dtype.kind in 'ifc' for dtype in df_with_data.dtypes):
    print("Plotting DataFrame with data:")
    df_with_data.plot(title="Data Plot")
    plt.show()
else:
    print("DataFrame with data is empty or has no numeric columns to plot.")

if not df_empty_check.empty and any(dtype.kind in 'ifc' for dtype in df_empty_check.dtypes):
    print("Plotting empty DataFrame (check):") # This won't run
    df_empty_check.plot()
    plt.show()
else:
    print("Empty DataFrame check: DataFrame is empty or has no numeric columns.")

Output:

Plotting DataFrame with data:
Empty DataFrame check: DataFrame is empty or has no numeric columns.
  • df.empty: Checks if the DataFrame has any data.
  • any(dtype.kind in 'ifc' for dtype in df.dtypes): Checks if any column has an integer (i), float (f), or complex (c) data type.

Choosing Columns for Plotting

When you call df.plot(), Pandas tries to plot all numeric columns. If you only want to plot specific numeric columns, select them first:

import pandas as pd
import matplotlib.pyplot as plt

df_converted = pd.DataFrame({
    'Year': [2020, 2021, 2022, 2023],
    'Revenue': [100.5, 120.2, 150.7, 180.0],
    'Expenses': [70.0, 80.0, 95.0, 110.0],
    'Region': ['North', 'South', 'North', 'West']
}).set_index('Year')


df_converted['Revenue'].plot(kind='line', title="Revenue Over Time", legend=True)
plt.ylabel("Amount (Millions)")
plt.show()

df_converted[['Revenue', 'Expenses']].plot(kind='area', title="Financials (Area Plot)", stacked=False)
plt.ylabel("Amount (Millions)")
plt.show()

Conclusion

The Pandas TypeError: no numeric data to plot arises primarily from two issues:

  1. Non-Numeric Columns: The columns you intend to plot are stored as strings (object dtype) or other non-numeric types. Solution: Clean the data if necessary (e.g., remove currency symbols, units like 'M') and then convert the columns to a numeric type using df['col'].astype(float) or pd.to_numeric(df['col'], errors='coerce').
  2. Empty DataFrame/Selection: The DataFrame or the subset of columns you're trying to plot contains no data. Solution: Ensure your DataFrame is populated and your selection results in at least one numeric column with data.

Always check df.dtypes to confirm your data types before plotting, and verify that your DataFrame is not empty. By ensuring your data is in the correct numeric format, you can leverage Pandas' powerful plotting capabilities.

Navigation