Search code examples
pythonsvgpygal

Center-align title in Pygal chart


I'm making a line chart in Pygal. I want to center the title of the chart, but I don't know how to do that.

I tried looking through the Pygal documentation, but I couldn't find anything relating to the alignment of a title. Here's what I have:

enter image description here

custom_style = Style(
    background = 'transparent',
    font_family='Avenir',
    colors = ['#14A1FF', '#14FF47'],
    opacity = .5)

chart = pygal.Line(
    style=custom_style, 
    print_values=True, 
    interpolate='hermite', 
    fill=True, dots_size=4, 
    show_y_guides=False,
    legend_at_bottom=True,
    legend_at_bottom_columns=2)

chart.title = "Rubik's Cube Solve Times Recorded Over Five Days"
chart.x_labels = ["1", "2", "3", "4", "5"]
chart.x_title = "Day"
chart.y_title = "Seconds"
chart.add("Average of 100", ao100)
chart.add("Average of 25", ao25)
chart.render_to_file('times.svg')

Solution

  • As mentioned in the comments the figure title is centred relative to the figure, rather than axes. This behaviour is hard-coded in the rendering functions, there are no configuration options that will change it.

    One workaround is to create your own class that inherits from pygal.Line and over-rides the function that renders the title (which isn't very large):

    class MyLineChart(pygal.Line):
    
        def __init__(self, *args, **kwargs):
            super(MyLineChart, self).__init__(*args, **kwargs)
    
        def _make_title(self):
            """Make the title"""
            if self._title:
                for i, title_line in enumerate(self._title, 1):
                    self.svg.node(
                        self.nodes['title'],
                        'text',
                        class_='title plot_title',
                        x=self.margin_box.left + self.view.width / 2, # Modified
                        y=i * (self.style.title_font_size + self.spacing)
                    ).text = title_line
    

    The _make_title function above was copied straight from the source code for the Graph class (the class that Line itself inherits from). The only change is in the line indicated with the comment 'Modified', this was taken from the function that renders the x axis label (because that is centred on the axes).

    With this you can replace chart = pygal.Line with chart = MyLineChart, but leave the rest of the code as it is. You might also want to change the name of the class to something more meaningful.