2025, Dec 02 05:00

How to create two-line Excel chart titles in openpyxl with per-line styling via DrawingML rich text

Learn how to set a multiline Excel chart title in openpyxl and style each line differently using DrawingML rich text XML, txPr, and Python code examples.

Building Excel charts with openpyxl often feels straightforward until you need granular control over the title. A common case is a two-line title where each line has different formatting, for example the first line with context like room and sample type, and a second line with acceptance criteria styled differently. Simply inserting a newline works for splitting lines, but it doesn’t let you change appearance per line using CharacterProperties. Here’s how to solve it cleanly.

Minimal example that only splits lines

The simple approach creates multiple lines, but gives no control over per-line styling:

from openpyxl.chart import BarChart

plot_obj = BarChart()
line_one = "Room: XXX, Sample Type: XXX, Grid: XXX"
line_two = "Acceptance Criteria: XXX"
plot_obj.title = line_one + "\n" + line_two

Why the above falls short

Setting a newline in the title produces a multiline label, but it doesn’t expose formatting options for each line. To style lines differently—bold, underline, color—you need to provide a title as rich text. With openpyxl this is achievable by reusing XML via Advanced Chart Formatting and feeding it as a rich text tree into the chart title.

Practical solution with rich text XML

The reliable route is to define the title using DrawingML rich text in a txPr block and assign it to the chart’s title as a rich object. You can prepare a test chart in Excel, set the title formatting there, inspect the chart XML, and reuse the relevant fragments. The example below shows how to apply two differently formatted lines. The newline character can be placed at the start of the next run or at the end of the previous run, depending on your preference.

from openpyxl.chart import BarChart, Reference
from openpyxl.chart.text import RichText
from openpyxl import Workbook
from openpyxl.xml.functions import fromstring

# Create workbook and target sheet
book = Workbook()
sheet = book.active

# Populate data
dataset = [
    ('val', 'Batch 1', 'Batch 2'),
    ('val_1', 10, 30),
    ('val_2', 40, 60),
    ('val_3', 50, 70),
    ('val_4', 20, 10),
    ('val_5', 10, 40),
    ('val_6', 50, 30),
]

for rec in dataset:
    sheet.append(rec)

# Rich text XML for a two-line title with distinct formatting
rich_text_xml = """

  
    
  
  
  
      
            
                
                    
                        
                        
                    
                
                
                
                
            
      
        
            
                
                    
                
            
            Chart Title1
        
        
            
                
                    
                
            
            \nChart Title2
         
  

"""

# Build chart
graph = BarChart()
graph.type = "bar"

# Title is required, but the visible text will be taken from the rich XML
graph.title = "Foo"

# Inject rich text into the chart title
graph.title.text.rich = RichText.from_tree(fromstring(rich_text_xml))

# Bind data and categories
value_ref = Reference(sheet, min_col=2, min_row=1, max_row=7, max_col=3)
name_ref = Reference(sheet, min_col=1, min_row=2, max_row=7)

graph.add_data(value_ref, titles_from_data=True)
graph.set_categories(name_ref)

# Size and placement
graph.height = 15
graph.width = 25
sheet.add_chart(graph, 'A10')

# Save
book.save('chart_result.xlsx')

Why this matters

Reports and dashboards often require mixed emphasis in titles, where context and acceptance criteria should be visually distinct. When a simple newline isn’t enough, rich text gives precise control over color, weight and underline for each line. Using advanced chart formatting lets you keep your chart generation fully automated without sacrificing presentation quality.

Takeaways

When you need a multiline chart title with line-specific formatting in openpyxl, split the lines with a newline in the text runs and supply a txPr-based rich text definition. Assign it to the chart via the rich text API, keeping a nominal title string. Adjust the newline placement either at the end of one run or the start of the next to control the break. If you prefer to tune styles visually, set up a title in a test chart and reuse the resulting XML. This approach provides the flexibility needed for polished, programmatic Excel charts.