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()
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With