I am trying to automate chart formatting for my work. Often times, we have to make 50+ charts with specific styles. The only difference with charts are axis titles, which have to be manually edited for client understanding. I already made a code that formats the chart to the exact format. The only problem is that I don't know how to specify formats only without specifying what the axis title should be. My code right is this.
import openpyxl as opyxl
from openpyxl.styles import Font
from openpyxl.chart.text import RichText
from openpyxl.drawing.text import Paragraph, ParagraphProperties, CharacterProperties, Font, RegularTextRun
from openpyxl.xml.functions import fromstring
from openpyxl.chart.shapes import GraphicalProperties
#The Point of This Program is to create a cleaner program
def graph_formatting(file, font_style = 'Times New Roman', fill_color = "000000", xt_name = "Default", yt_name = "Default", font_size = 1000, bold = '0'):
wb = opyxl.load_workbook(file)
for sheets in wb.chartsheets: #loops through available chartsheets
dechart = sheets._charts[0]
#This specifies the axis format using XML;
xml = f"""
<txPr>
<a:p xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:r>
<a:rPr b="{bold}" i="0" sz="{font_size}" spc="-1" strike="noStrike">
<a:solidFill>
<a:srgbClr val="{fill_color}" />
</a:solidFill>
<a:latin typeface="{font_style}" />
</a:rPr>
<a:t>{yt_name}</a:t>
</a:r>
</a:p>
</txPr>
"""
dechart.y_axis.title.tx.rich = RichText.from_tree(fromstring(xml)) #Change the format using specified XML;
#Same idea
xml = f"""
<txPr>
<a:p xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:r>
<a:rPr b="{bold}" i="0" sz="{font_size}" spc="-1" strike="noStrike">
<a:solidFill>
<a:srgbClr val="{fill_color}" />
</a:solidFill>
<a:latin typeface="{font_style}" />
</a:rPr>
<a:t>{xt_name}</a:t>
</a:r>
</a:p>
</txPr>
"""
dechart.x_axis.title.tx.rich = RichText.from_tree(fromstring(xml))
#Changes rest of the of charts, uch as axis labels
font = Font(typeface=font_style) #set the font
size = font_size #set the font size
cp = CharacterProperties(latin=font, sz=size, b=False)
pp = ParagraphProperties(defRPr=cp)
dechart.x_axis.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)]) #changes the x axis label font
dechart.y_axis.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)]) #changes the y axis label font
#chart styling for the minor details
dechart.graphical_properties = GraphicalProperties()
dechart.graphical_properties.line.noFill = True
dechart.graphical_properties.line.prstDash = None
dechart.x_axis.graphicalProperties.line.solidFill = fill_color #changes the line color
dechart.y_axis.graphicalProperties.line.noFill=False #draws the y axis line
dechart.y_axis.majorGridlines = None #gets rid of gridline
dechart.y_axis.majorTickMark = 'out' #create tickmarks for x and y axis
dechart.x_axis.majorTickMark = 'out'
#wb.save(path)
if dechart:
wb.save(file)
It works for the most part. I just want to keep the existing axis title as is. For example, if the axis title says "Percent of Customer", then it should still say "Percent of Customer" after I run the program, not "Default". I tried to delete the line
<a:t>{yt_name}</a:t>
in the XML, but now it just erases the axis title. I tried to look through the openpyxl documentation, but I can't find a solution.
The ideal workflow with this program is:
The problem is when I use the program the second time, the older axis titles in older charts will get overridden by "Default"
Do you mean like grab the original titles and reset them after your formatting
...
for sheets in wb.chartsheets: #loops through available chartsheets
dechart = sheets._charts[0]
### Get original X and Y Axis titles
orig_x_title = dechart.x_axis.title.text.rich.paragraphs[0].text[0].value
orig_y_title = dechart.y_axis.title.text.rich.paragraphs[0].text[0].value
print(f"Original X AXIS Title text '{orig_x_title}'")
print(f"Original Y AXIS Title text '{orig_y_title}'")
#This specifies the axis format using XML;
xml = f"""
<txPr>
<a:p xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:r>
<a:rPr b="{bold}" i="0" sz="{font_size}" spc="-1" strike="noStrike">
<a:solidFill>
<a:srgbClr val="{fill_color}" />
</a:solidFill>
<a:latin typeface="{font_style}" />
</a:rPr>
<a:t>{yt_name}</a:t>
</a:r>
</a:p>
</txPr>
"""
dechart.y_axis.title.tx.rich = RichText.from_tree(fromstring(xml)) #Change the format using specified XML;
#Same idea
xml = f"""
<txPr>
<a:p xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:r>
<a:rPr b="{bold}" i="0" sz="{font_size}" spc="-1" strike="noStrike">
<a:solidFill>
<a:srgbClr val="{fill_color}" />
</a:solidFill>
<a:latin typeface="{font_style}" />
</a:rPr>
<a:t>{xt_name}</a:t>
</a:r>
</a:p>
</txPr>
"""
#dechart.x_axis.title.tx.rich = RichText.from_tree(fromstring(xml))
### Reset Axis Titles text to orig
dechart.x_axis.title = orig_x_title
dechart.y_axis.title = orig_y_title
#Changes rest of the of charts, uch as axis labels
font = Font(typeface=font_style) #set the font
size = font_size #set the font size
...