Yanirmr
Yanirmr

Reputation: 1032

How to set a reusable layout in plotly?

My goal was to maintain uniformity when designing some Plotly graphs for a small Python project.

After I defined a layout, I tried using it as an object or variable, but I couldn't figure out how to do it.

import plotly.express as px

df = px.data.gapminder().query("country=='Canada'")
fig = px.line(df, x="year", y="lifeExp", title='Life expectancy in Canada')
fig.show()

# basic graphic manipulation
fig.update_layout(xaxis_range=[1970, 2000])
fig.update_layout(font_size=20)
fig.show()

I couldn't figure out how to do the same manipulation on a different figure without duplicate code. In the Plotly line chart documentation, I am unable to find the relevant parameters,

What I expected was:

desired_layout = dict(font_size = 20, xaxis_range=[1970, 2000])

fig = px.line(df, x="year", y="lifeExp", title='Life expectancy in Canada', layout = desired_layout)
#or:
fig = px.line(df, x="year", y="lifeExp", title='Life expectancy in Canada', **desired_layout)

However, none of them work for me.

Are there any other options?

Upvotes: 3

Views: 1266

Answers (3)

vestland
vestland

Reputation: 61074

This would depend on your actual use-case and the similarities between the plots, but I would apply changes to your existing figure fig, like this:

fig.update_layout(xaxis_range=[1970, 2000], xaxis_tickfont_size=20, xaxis_gridcolor = 'black', showlegend = True)

And then just grab the full layout from there with:

desired_layout = fig.layout

Another option is:

desired_layout = fig.to_dict()['layout']

Or if you'd like to grab some more details:

f = fig.full_figure_for_development(warn=False)
desired_layout = f.layout()

And then you can build another figure like this and apply your desired layout:

df = px.data.gapminder().query("country=='Uganda'")
fig = px.line(df, x = 'year', y = 'lifeExp')
fig.update_layout(desired_layout)
fig.show()

Plot 1:

enter image description here

Plot 2:

enter image description here

Complete code:

import plotly.express as px

df = px.data.gapminder().query("country=='Canada'")

fig = px.line(df, x = 'year', y = 'lifeExp')

fig.update_layout(xaxis_range=[1970, 2000], xaxis_tickfont_size=20, xaxis_gridcolor = 'black', showlegend = True)

desired_layout = fig.layout
# desired_layout = fig.to_dict()['layout']

# f = fig.full_figure_for_development(warn=False)
# desired_layout = f.to_dict['layout']

df = px.data.gapminder().query("country=='Uganda'")
fig2 = px.line(df, x = 'year', y = 'lifeExp')
fig2.update_layout(desired_layout)
fig2.show()

Upvotes: 2

BalticCygnus
BalticCygnus

Reputation: 36

In theory, the following code should work:

import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go

pio.templates["new_template"] = go.layout.Template(
    layout={"font": {"size": 20}, "xaxis": {"range": [1970, 2000]}}
)

df = px.data.gapminder().query("country=='Canada'")
fig = px.line(
    df,
    x="year",
    y="lifeExp",
    title="Life expectancy in Canada",
    template="new_template",
)
fig.show()

However, setting up default range seems buggy.

But there are alternatives:

  1. Extra line
fig.update_layout(xaxis_range=[1970, 2000])
  1. Filter dataframe
import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go

pio.templates["new_template"] = go.layout.Template(
    layout={"font": {"size": 20}, "xaxis": {"range": [1970, 2000]}}
)

df = px.data.gapminder().query("country=='Canada'")
fig = px.line(
    df.loc[(df["year"] >= 1970) & (df["year"] <= 2000)],
    x="year",
    y="lifeExp",
    title="Life expectancy in Canada",
    template="new_template",
)
fig.show()
  1. Define function
import plotly.express as px

df = px.data.gapminder().query("country=='Canada'")

def default_line(min_year, max_year, default_font, df):
    fig = px.line(
        df,
        x="year",
        y="lifeExp",
        title="Life expectancy in Canada"
    )
    fig.update_layout(xaxis_range=[min_year, max_year], font_size=default_font)
    return fig
default_line(1970, 2000, 20, df)

Upvotes: 0

Yanirmr
Yanirmr

Reputation: 1032

As other responders have mentioned, there is no direct way to do that.

I found it easiest to pack the desired features in a dictionary, then unpack them as follows:

import plotly.express as px

df = px.data.gapminder().query("country=='Canada'")

# define the desired layout
desired_layout = dict(xaxis_range=[1970, 2000], font_size=20) #and so on

fig = px.line(df, x="year", y="lifeExp", title='Life expectancy in Canada')
fig.update_layout(**desired_layout) # or just: fig.update_layout(desired_layout)
fig.show()

Upvotes: 1

Related Questions