Python Forum

Full Version: Multiple user defined plots with secondary axes using for loop
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I need help on plotting multiple x-y plots based on dynamic user inputs in one subplot using multiple secondary axes. That is, the user would specify how many lines he needs to draw on the same plot, and which parameters the user would choose to plot.

I could do this using static code. I tried using a for loop with the same code, but I am getting stuck with defining dynamic axes ax2, ax3, ax4 as twin of ax and so on. Here is the static code that works and also my attempt at dynamic code which failed miserably (lines commented out). The csv file used is also attached.

Static Code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time
from mpl_toolkits.axes_grid1 import host_subplot

df1 = pd.read_csv("Data1.csv",skiprows=0)

x=df1['time']
y1=df1['area']
y2=df1['volume']
y3=df1['mrp']
y4=df1['perimeter']

plt.figure(figsize=(20,12))
ax = host_subplot(111, axes_class=axisartist.Axes)
ax2 = ax.twinx()
ax3 = ax.twinx()
ax4 = ax.twinx()

ax2.axis["left"] = ax2.new_fixed_axis(loc="left", offset=(-50, 0))
ax3.axis["right"] = ax3.new_fixed_axis(loc="right", offset=(0, 0))
ax4.axis["right"] = ax4.new_fixed_axis(loc="right", offset=(50, 0))

p1, = ax.plot(x,y1, label="Area")
p2, = ax2.plot(x,y2, label="Volume")
p3, = ax3.plot(x,y3, label="MRP")
p4, = ax4.plot(x,y4, label="Perimeter")

ax.set_xlabel("Time")
ax.set_ylabel("Y1")
ax2.set_ylabel("Y2")
ax3.set_ylabel("Y3")
ax4.set_ylabel("Y4")

ax.axis["left"].label.set_color(p1.get_color())
ax2.axis["left"].label.set_color(p2.get_color())
ax3.axis["right"].label.set_color(p3.get_color())
ax4.axis["right"].label.set_color(p4.get_color())

ax.legend()

plt.show()
Dynamic Code Based on User Input

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time
from mpl_toolkits.axes_grid1 import host_subplot

df1 = pd.read_csv("Data1.csv",skiprows=0)

x=df1['time']
y1=df1['area']
y2=df1['volume']
y3=df1['mrp']
y4=df1['perimeter']

n=int(input('Enter number of parameters you want to plot in one plot area (max 4, 0 to quit):')) # user chooses how many parameters to plot
if (n==0 or n > 4):
    print('Exiting....')
    time.sleep(2)
else:
    x=[] # collect x data (in this case, the same x data is used for all lines)
    y=[] # collect y data
    for i in range(n):
        pars=int(input('Enter parameter:\n 1 for Area, 2 for Volume, 3 for MRP, 4 for Perimeter:')) # user chooses which parameters to plot
        if (pars ==1):
            x.append(t) # append to x[] list
            y.append(y1) # append to y[] list
        elif (pars == 2):
            x.append(t)
            y.append(y2)
        elif (pars == 3):
            x.append(t)
            y.append(y3)
        elif (pars == 4):
            x.append(t)
            y.append(y4)

data = zip(x,y)
def plot_in_loop(data):
    fig, ax = plt.subplots(figsize=(20,12))
    for idx,xy in enumerate(data,1): # use enumerator as for loop counter
# PLEASE DONT TRY TO MAKE SENSE OF THE COMMENTED LINES. 
# IF YOU COMPARE WITH STATIC CODE, YOU WOULD KNOW WHAT I WAS TRYING TO DO
#        'ax'+str(idx)=ax.twinx() # to get ax2 = ax.twinx() & ax3=ax.twinx() 
#        ax[idx].axis["left"] = ax[idx].new_fixed_axis(loc="left", offset=(-idx*50, 0)) 
#        p[idx], = ax[idx].plot(x[idx],y[idx], label="Y2")
#        ax[idx].set_ylabel("Y2")
#        ax[idx].axis["right"].label.set_color(p[idx].get_color())
        return fig, ax 
    plt.show()      

fig, ax = loop_plot(plots)
I forgot to mention that I am new to programming. I have used existing code from some forums and edited/ suited to my requirement. It must be fairly obvious I'm sure. I feel that by using zip and enumerator, I have complicated the code. Any suggestion would be greatly appreciated. Thanks.