Issue
I need help with dynamically plotting columns of data from an excel file using matplotlib. The plot should have multiple Y-axes placed equally on the right and left sides of the chart if the number of columns is even and one axis more on the right if odd. The closest code I have will place the axes on the right side and not properly on the left side
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
elif i%2 == 0:
ax = ax_orig.twinx()
ax.spines['right'].set_position(('outward', 50 * (i - 1)))
else:
ax = ax_orig.twinx()
ax.spines['left'].set_position(('outward', 50 * (i - 2)))
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()
Solution
You're close but missing a few pieces. Rather than just changing the yaxis you need to instantiate different plots for each data (docs). I am also a little confused about the labeling of the spines, but it seems that another line is necessary to change the side of the plot the yaxis is associated with, one for the ylabel, and finally the line you had to change its offset. This code essentially plots all datas on to the same vertical scale, but with different yaxis to differentiate.
import matplotlib.pyplot as plt
import numpy as np
# Create some mock data
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)
data3 = 10*t
data4 = 10*t**2
datas = [data1, data2, data3, data4]
colors = ['tab:red', 'tab:blue', 'tab:green', 'tab:orange']
fig, ax1 = plt.subplots()
# plot first data like normal
color = colors[0]
ax1.set_xlabel('time (s)')
ax1.set_ylabel('exp', color=color)
ax1.plot(t, data1, color=color)
ax1.tick_params(axis='y', labelcolor=color)
for i, (d, color) in enumerate(zip(datas[1:], colors[1:])):
ax = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax.set_ylabel('sin', color=color) # we already handled the x-label with ax1
ax.plot(t, d, color=color, marker='o')
ax.tick_params(axis='y', labelcolor=color)
# set position to the right if an even number
if i%2 == 0:
ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
ax.spines['right'].set_position(('outward', 50 * (i)))
# set position to the right if an odd number and the last one
elif i%2 == 1 and i == len(datas) - 1:
ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
ax.spines['right'].set_position(('outward', 50 * (i)))
# set position to the left if an odd number and not the last one
else:
ax.yaxis.tick_left()
ax.yaxis.set_label_position("left")
ax.spines['left'].set_position(('outward', 50 * (i + 1)))
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
Answered By - heavykangaroo
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.