6

I am recently exploring Plotly and I wonder if there is a way for sharing a plot and let the viewer switch between a logarithmic axis and linear axis.

Any suggestion?

Stefano
  • 359
  • 1
  • 5
  • 16

2 Answers2

11

Plotly has a dropdown feature which allows the user to dynamically update the plot styling and/or the traces being displayed. Below is a minimal working example of a plot where the user can switch between a logarithmic and linear scale.

import plotly
import plotly.graph_objs as go


x = [1, 2, 3]
y = [1000, 10000, 100000]
y2 = [5000, 10000, 90000]

trace1 = go.Bar(x=x, y=y, name='trace1')
trace2 = go.Bar(x=x, y=y2, name='trace2', visible=False)


data = [trace1, trace2]

updatemenus = list([
    dict(active=1,
         buttons=list([
            dict(label='Log Scale',
                 method='update',
                 args=[{'visible': [True, True]},
                       {'title': 'Log scale',
                        'yaxis': {'type': 'log'}}]),
            dict(label='Linear Scale',
                 method='update',
                 args=[{'visible': [True, False]},
                       {'title': 'Linear scale',
                        'yaxis': {'type': 'linear'}}])
            ]),
        )
    ])

layout = dict(updatemenus=updatemenus, title='Linear scale')
fig = go.Figure(data=data, layout=layout)

plotly.offline.iplot(fig)

I added two traces to the data list to show how traces can also be added or removed from a plot. This can be controlled by the visible list in updatemenus for each button.

daronjp
  • 684
  • 8
  • 9
  • Even though this answer works, the label of the y axis is disappearing when I change the scale. Any way to avoid this? – user171780 Dec 15 '20 at 15:38
  • @user171780 you'll need to add the title to each of the `buttons` as well as in the `layout`. The `layout` sets the chart properties for the initial load. The `buttons` set the chart properties for each sub-chart. Ex: for the first button `'yaxis': {'type': 'log', 'title': 'My Log Axis'}`. Make the corresponding change for the second button as well. Then update the `layout` to `layout = dict(updatemenus=updatemenus, title='Linear scale', yaxis={'title': 'My Linear Axis'})`. – daronjp Dec 15 '20 at 23:57
-1

If anyone is wanting to do this in a Python Dash app, here is one possible route (similar to the answer I provided for this question, but this uses go.Figure to make the graph):

import plotly
import plotly.graph_objs as go
import dash
from dash import html, dcc, callback, Output, Input


x = [1, 2, 3]
y = [1000, 10000, 100000]
y2 = [5000, 10000, 90000]

trace1 = go.Bar(x=x, y=y, name='trace1')
trace2 = go.Bar(x=x, y=y2, name='trace2', visible=False)

data = [trace1, trace2]

app = Dash(__name__)

app.layout = html.Div([
    #Radio buttons for user to select their desired scale
    dcc.RadioItems(
        id = 'y-axis-scale-selection', 
        options = ['linear', 'log'],
        value = 'Linear' #Set to have default linear axis
        )
    #Output graph
    dcc.Graph(id = 'my_graph')
])

#Create graph that will have the desired axis scale 
@app.callback(
    Output('my_graph', 'figure'),
    Input('y-axis-scale-selection', 'value'),
    )

def get_graph(selected_scale):
    if selected_scale == "log": #If the user selects the log scale
        fig = go.Figure(data=data)
        fig.update_layout(yaxis_type = "log")
    else: #Default plot will have linear scale
        fig = go.Figure(data=data)
        
    return fig

if __name__ == '__main__':
    app.run(debug=True)
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/34831058) – Lajos Arpad Aug 12 '23 at 18:18
  • Hi! Thanks for the feedback (still new to stackoverflow). I hope that the changes I made have helped :) – jessieolough Aug 28 '23 at 13:16