TypeError: expected <class 'openpyxl.chart.axis.NumericAxis'> in OpenPyxl – Causes and Solutions


I recently encountered an error in OpenPyXL that seemed simple at first but became quite frustrating: "TypeError: expected <class 'openpyxl.chart.axis.NumericAxis'>". After some research and trial-and-error, I realized it’s a pretty common issue for anyone dealing with charts in Excel using OpenPyXL, especially when working with the chart.axis.NumericAxis class.

In this article, I’ll walk you through how I tackled this problem and gathered solutions from multiple trusted sources to ensure you have everything you need to fix this issue if you encounter it yourself.

What’s the Cause?

This error often pops up when you're trying to manipulate or generate Excel charts in OpenPyXL, a popular Python library for working with Excel files. The root cause of the issue usually boils down to the improper handling of chart objects or incorrect axis types being passed into the chart classes. Specifically, OpenPyXL expects an axis to be of type NumericAxis, but due to incorrect implementation or library updates, you might be passing an invalid type or something that the library doesn't expect.

Common Scenarios Where This Error Occurs

From my experience, and after diving into multiple community threads, this error typically happens in the following scenarios:

  • Loading Workbooks with Charts: If you're working with a workbook that already contains charts and try to load it using OpenPyXL, this error can pop up due to a mismatch in how axes are referenced.
  • Creating Charts Programmatically: When you're creating charts dynamically in Python, especially scatter charts or other chart types that involve numeric axes, you might run into this issue.
  • Library Version Conflicts: Changes between different OpenPyXL versions can also cause this error, where older versions used certain types of axes and newer versions expect something different.

Solutions to Fix the "TypeError: expected <class 'openpyxl.chart.axis.NumericAxis'>"

After a lot of trial and error (and some help from online resources), here’s how you can resolve this issue.

1. Ensure You're Passing the Correct Axis Type

The first thing you should check is whether you're passing the correct axis type when creating charts. OpenPyXL expects NumericAxis in certain chart types like ScatterChart, but in cases where you're using a different axis type or none at all, this error will occur. Here’s how to fix that:

from openpyxl import Workbook
from openpyxl.chart import ScatterChart, Reference
from openpyxl.chart.axis import NumericAxis

# Create workbook and worksheet
wb = Workbook()
ws = wb.active

# Sample data for chart
data = [
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
]

# Adding data to the worksheet
for row in data:
    ws.append(row)

# Create scatter chart
chart = ScatterChart()

# Define X and Y axis using NumericAxis
x_axis = NumericAxis()
y_axis = NumericAxis()

# Set axis to the chart
chart.x_axis = x_axis
chart.y_axis = y_axis

# Add the chart to the worksheet
ws.add_chart(chart, "E5")

wb.save("chart_test.xlsx")

2. Upgrade OpenPyXL to the Latest Version

If you’re using an outdated version of OpenPyXL, upgrading to the latest stable version might resolve the issue. This is because the library frequently gets bug fixes and new features, including better support for charts and axes.

pip install --upgrade openpyxl

Always make sure you’re using the most recent version of OpenPyXL, as older versions can have compatibility issues with new Excel file formats.

3. Workaround for Pre-existing Workbooks

If you're trying to load a pre-existing workbook that already contains charts, the error might be due to the way the workbook stores chart axis types. You can try manually updating or re-assigning axis properties after loading the workbook.

from openpyxl import load_workbook

wb = load_workbook("existing_chart.xlsx")
ws = wb.active

# Re-assign axis to correct type
for chart in ws._charts:
    if isinstance(chart.x_axis, NumericAxis) == False:
        chart.x_axis = NumericAxis()
    if isinstance(chart.y_axis, NumericAxis) == False:
        chart.y_axis = NumericAxis()

wb.save("updated_chart.xlsx")

4. Explicitly Set Axis Properties

Sometimes, simply setting the axis properties explicitly can fix the issue. For example, if you’re working with a scatter chart, ensure that the axis type is numeric:

chart.x_axis.number_format = 'General'
chart.y_axis.number_format = 'General'

This ensures that OpenPyXL interprets the axis data as numbers, reducing the chances of running into this error.

Running into the "TypeError: expected <class 'openpyxl.chart.axis.NumericAxis'>" can be frustrating, but with these solutions, you should be able to fix it in no time. Whether it’s updating the library, ensuring correct axis types