Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using a loop to define multiple y axes in plotly

I have to plot lines on multiple y-axes. In plotly, however, the axis generation within go.Layout is quite verbose like in this example from the plotly documentation: https://plot.ly/python/multiple-axes/

layout = go.Layout(
title='multiple y-axes example',
width=800,
xaxis=dict(
    domain=[0.3, 0.7]
),
yaxis=dict(
    title='yaxis title',
    titlefont=dict(
        color='#1f77b4'
    ),
    tickfont=dict(
        color='#1f77b4'
    )

## repeat for every new y-axis.

In matplotlib i like to save code by generating all the different axes and handling the plotting in loops like so:

import matplotlib.pyplot as plt
import numpy as np

# generate dummy data
data = []
for i in range(5):
    arr = np.random.random(10) * i
    data.append(arr)

colors = ['black', 'red', 'blue', 'green', 'purple']
labels = ['label1', 'label2', 'label3', 'label4', 'label5']

# define other paramters (e.g. linestyle etc.) in lists

fig, ax_orig = plt.subplots(figsize=(10, 5))
for i, (arr, color, label) in enumerate(zip(data, colors, labels)):
    if i == 0:
        ax = ax_orig
    else:
        ax = ax_orig.twinx()
        ax.spines['right'].set_position(('outward', 50 * (i - 1)))
    ax.plot(arr, color=color, marker='o')
    ax.set_ylabel(label, color=color)
    ax.tick_params(axis='y', colors=color)
fig.tight_layout()
plt.show()

figure generated by example

Due to the dict-syntax used in object generation I seem to be unable to make something like that work in plotly. I have tried generating the axes-dicts by loops in advance and passing those to go.Layout but with no success. If anybody could point out an elegant way to reduce redundancy it will be greatly appreciated.

All the best and thanks in advance.

like image 853
zeawoas Avatar asked Oct 20 '25 14:10

zeawoas


1 Answers

You could take advantage of Python's **kwargs, i.e. you create a dictionary which contains all your layout values and passes it to Plotly's layout.

import numpy as np
import plotly

plotly.offline.init_notebook_mode()

# generate dummy data, taken from question
data = []
for i in range(5):
    arr = np.random.random(10) * i
    data.append(arr)

labels = ['label1', 'label2', 'label3', 'label4', 'label5']

plotly_data = []
plotly_layout = plotly.graph_objs.Layout()

# your layout goes here
layout_kwargs = {'title': 'y-axes in loop',
                 'xaxis': {'domain': [0, 0.8]}}

for i, d in enumerate(data):
    # we define our layout keys by string concatenation
    # * (i > 0) is just to get rid of the if i > 0 statement
    axis_name = 'yaxis' + str(i + 1) * (i > 0)
    yaxis = 'y' + str(i + 1) * (i > 0)
    plotly_data.append(plotly.graph_objs.Scatter(y=d, 
                                                 name=labels[i]))
    layout_kwargs[axis_name] = {'range': [0, i + 0.1],
                                'position': 1 - i * 0.04}

    plotly_data[i]['yaxis'] = yaxis
    if i > 0:
        layout_kwargs[axis_name]['overlaying'] = 'y'

fig = plotly.graph_objs.Figure(data=plotly_data, layout=plotly.graph_objs.Layout(**layout_kwargs))
plotly.offline.iplot(fig)

enter image description here

like image 87
Maximilian Peters Avatar answered Oct 22 '25 04:10

Maximilian Peters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!