Search code examples
pythonplotlyvisualization

Create a template for multiple figures using Plotly in Python


I am trying to create a template for a heatmap and a line chart using Plotly in Python. I want to use the combination of this template as well as the plotly_white. However, combining them remove the colors of the colorscale for my heatmap.

Combining my template with the plotly_white removes the color of the heatmap

The colorscale I want for my heatmap are those. I still get them by only using mytemplate

I define my template in the following function

THEME = {
    'background_color': '#ffffff',
    'font_family': 'Roboto',
    'accent_font_family': 'Roboto Slab',
    'dark_color': '#2A2B2E',
    'pale_color': '#DFD9E2',
    'line_chart_color': 'black',
    'label_font_size': 14,
    'label_background_color': '#ffffff',
    'colorscale': 'Bluyl'
}
def create_custom_theme():
    pio.templates['mytemplate'] = go.layout.Template(
        layout=go.Layout(
            font=dict(
                family=THEME['font_family']+' , '+ THEME['accent_font_family'],
                color=THEME['dark_color']
            ),
            paper_bgcolor=THEME['background_color'],
            plot_bgcolor=THEME['background_color'],
            hoverlabel=dict(
                bgcolor=THEME['label_background_color'],
                font=dict(
                    size=THEME['label_font_size']
                )
            ),
            hovermode="closest",
            newshape=dict(
                line_color=THEME['line_chart_color']
            ),
            colorscale=dict(diverging=THEME['colorscale']), 
            xaxis=dict(
                tickangle=-45
            )
        )
    )

And set it as default like this

def set_default_theme():
    pio.templates.default='mytemplate+plotly_white'

Also, I am wondering if it is possible to use the two font families defined in the template, in the hovertemplate. For now, I use span to avoid using the template

def get_heatmap_hover_template():
    return ('<span style="font-family: Roboto Slabk"><b>Neighborhood : </b></span>%{y}'
            +'<br><span style="font-family: Roboto Slabk"><b>Year : </b></span>%{x}</br>'
            +'<span style="font-family: Roboto Slabk"><b>Trees planted : </b></span>%{z}<extra></extra>')

Solution

  • You were almost there. Here is what you should do:

    import plotly.io as pio
    import plotly.graph_objects as go
    
    THEME = {
        'background_color': '#ffffff',
        'font_family': 'Roboto',
        'accent_font_family': 'Roboto Slab',
        'dark_color': '#2A2B2E',
        'pale_color': '#DFD9E2',
        'line_chart_color': 'black',
        'label_font_size': 14,
        'label_background_color': '#ffffff',
        'colorscale': 'Bluyl'
    }
    
    def create_custom_theme():
        pio.templates['mytemplate'] = go.layout.Template(
            layout=go.Layout(
                font=dict(
                    family=THEME['font_family']+', '+THEME['accent_font_family'],
                    color=THEME['dark_color']
                ),
                paper_bgcolor=THEME['background_color'],
                plot_bgcolor=THEME['background_color'],
                hoverlabel=dict(
                    bgcolor=THEME['label_background_color'],
                    font=dict(
                        size=THEME['label_font_size']
                    )
                ),
                hovermode="closest",
                newshape=dict(
                    line_color=THEME['line_chart_color']
                ),
                coloraxis=dict(
                    colorscale=THEME['colorscale']
                ),
                xaxis=dict(
                    tickangle=-45
                )
            )
        )
    
    create_custom_theme()
    
    def set_default_theme():
        pio.templates.default = 'mytemplate+plotly_white'
    
    set_default_theme()
    
    def get_heatmap_hover_template():
        return ('<span style="font-family: Roboto Slab"><b>Neighborhood : </b></span>%{y}'
                +'<br><span style="font-family: Roboto Slab"><b>Year : </b></span>%{x}</br>'
                +'<span style="font-family: Roboto Slab"><b>Trees planted : </b></span>%{z}<extra></extra>')
    
    heatmap_data = [
        [1, 20, 30],
        [20, 1, 60],
        [30, 60, 1]
    ]
    
    line_data = [1, 2, 3, 4, 5]
    
    heatmap = go.Figure(data=go.Heatmap(
        z=heatmap_data,
        colorscale=THEME['colorscale'],
        hovertemplate=get_heatmap_hover_template()
    ))
    
    line_chart = go.Figure(data=go.Scatter(
        y=line_data,
        mode='lines',
        line=dict(color=THEME['line_chart_color'])
    ))
    
    heatmap.show()
    line_chart.show()
    

    To combine the custom template with plotly_white while preserving the colorscale you need to make sure that the colorscale settings are not overridden when merging the templates.

    enter image description here enter image description here

    Update To specify the colorscale directly in your custom theme so that you don't need to specify it again when creating the heatmap. You can do this by defining the colorscale within the coloraxis in the layout template and then applying this coloraxis to the heatmap.

    import plotly.io as pio
    import plotly.graph_objects as go
    
    THEME = {
        'background_color': '#ffffff',
        'font_family': 'Roboto',
        'accent_font_family': 'Roboto Slab',
        'dark_color': '#2A2B2E',
        'pale_color': '#DFD9E2',
        'line_chart_color': 'black',
        'label_font_size': 14,
        'label_background_color': '#ffffff',
        'colorscale': 'Bluyl'
    }
    
    def create_custom_theme():
        pio.templates['mytemplate'] = go.layout.Template(
            layout=go.Layout(
                font=dict(
                    family=THEME['font_family']+', '+THEME['accent_font_family'],
                    color=THEME['dark_color']
                ),
                paper_bgcolor=THEME['background_color'],
                plot_bgcolor=THEME['background_color'],
                hoverlabel=dict(
                    bgcolor=THEME['label_background_color'],
                    font=dict(
                        size=THEME['label_font_size']
                    )
                ),
                hovermode="closest",
                newshape=dict(
                    line_color=THEME['line_chart_color']
                ),
                coloraxis=dict(
                    colorscale=THEME['colorscale']
                ),
                xaxis=dict(
                    tickangle=-45
                )
            )
        )
    
    create_custom_theme()
    
    def set_default_theme():
        pio.templates.default = 'mytemplate+plotly_white'
    
    set_default_theme()
    
    def get_heatmap_hover_template():
        return ('<span style="font-family: Roboto Slab"><b>Neighborhood : </b></span>%{y}'
                +'<br><span style="font-family: Roboto Slab"><b>Year : </b></span>%{x}</br>'
                +'<span style="font-family: Roboto Slab"><b>Trees planted : </b></span>%{z}<extra></extra>')
    
    heatmap_data = [
        [1, 20, 30],
        [20, 1, 60],
        [30, 60, 1]
    ]
    
    line_data = [1, 2, 3, 4, 5]
    
    heatmap = go.Figure(data=go.Heatmap(
        z=heatmap_data,
        coloraxis="coloraxis",  
        hovertemplate=get_heatmap_hover_template()
    ))
    
    line_chart = go.Figure(data=go.Scatter(
        y=line_data,
        mode='lines',
        line=dict(color=THEME['line_chart_color'])
    ))
    
    heatmap.show()
    line_chart.show()