<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Python API to BeakerX Interactive Plotting
You can access Beaker's native interactive plotting library from Python.
Plot with simple properties
Python plots has syntax very similar to Groovy plots. Property names are the same.
Step1:  Plot items
Lines, Bars, Points and Right yAxis
Step2:  Lines,  Points with Pandas
Step3:  Areas, Stems and Crosshair
Step4:  Constant Lines, Constant Bands
Step5:  TimePlot
Step6:  numpy datatime64
Step7:  Timestamp
Step8:  Datetime and date
Step9:  NanoPlot
Step10:  Stacking
Step11:  SimpleTime Plot
Step12:  Second Y Axis
The plot can have two y-axes. Just add a YAxis to the plot object, and specify its label.
Then for data that should be scaled according to this second axis,
specify the property yAxis with a value that coincides with the label given.
You can use upperMargin and lowerMargin to restrict the range of the data leaving more white, perhaps for the data on the other axis.
Step13:  Combined Plot
<ASSISTANT_TASK:>
Python Code:
from beakerx import *
import pandas as pd
tableRows = pd.read_csv('../resources/data/interest-rates.csv')
Plot(title="Title",
     xLabel="Horizontal",
     yLabel="Vertical",
     initWidth=500,
     initHeight=200)
Explanation: Python API to BeakerX Interactive Plotting
You can access Beaker's native interactive plotting library from Python.
Plot with simple properties
Python plots has syntax very similar to Groovy plots. Property names are the same.
End of explanation
x = [1, 4, 6, 8, 10]
y = [3, 6, 4, 5, 9]
pp = Plot(title='Bars, Lines, Points and 2nd yAxis', 
          xLabel="xLabel", 
          yLabel="yLabel", 
          legendLayout=LegendLayout.HORIZONTAL,
          legendPosition=LegendPosition.RIGHT,
          omitCheckboxes=True)
pp.add(YAxis(label="Right yAxis"))
pp.add(Bars(displayName="Bar", 
       x=[1,3,5,7,10], 
       y=[100, 120,90,100,80], 
       width=1))
pp.add(Line(displayName="Line", 
            x=x, 
            y=y, 
            width=6, 
            yAxis="Right yAxis"))
pp.add(Points(x=x, 
              y=y, 
              size=10, 
              shape=ShapeType.DIAMOND,
              yAxis="Right yAxis"))
plot = Plot(title= "Setting line properties")
ys = [0, 1, 6, 5, 2, 8]
ys2 = [0, 2, 7, 6, 3, 8]
plot.add(Line(y= ys, width= 10, color= Color.red))
plot.add(Line(y= ys, width= 3, color= Color.yellow))
plot.add(Line(y= ys, width= 4, color= Color(33, 87, 141), style= StrokeType.DASH, interpolation= 0))
plot.add(Line(y= ys2, width= 2, color= Color(212, 57, 59), style= StrokeType.DOT))
plot.add(Line(y= [5, 0], x= [0, 5], style= StrokeType.LONGDASH))
plot.add(Line(y= [4, 0], x= [0, 5], style= StrokeType.DASHDOT))
plot = Plot(title= "Changing Point Size, Color, Shape")
y1 = [6, 7, 12, 11, 8, 14]
y2 = [4, 5, 10, 9, 6, 12]
y3 = [2, 3, 8, 7, 4, 10]
y4 = [0, 1, 6, 5, 2, 8]
plot.add(Points(y= y1))
plot.add(Points(y= y2, shape= ShapeType.CIRCLE))
plot.add(Points(y= y3, size= 8.0, shape= ShapeType.DIAMOND))
plot.add(Points(y= y4, size= 12.0, color= Color.orange, outlineColor= Color.red))
plot = Plot(title= "Changing point properties with list")
cs = [Color.black, Color.red, Color.orange, Color.green, Color.blue, Color.pink]
ss = [6.0, 9.0, 12.0, 15.0, 18.0, 21.0]
fs = [False, False, False, True, False, False]
plot.add(Points(y= [5] * 6, size= 12.0, color= cs))
plot.add(Points(y= [4] * 6, size= 12.0, color= Color.gray, outlineColor= cs))
plot.add(Points(y= [3] * 6, size= ss, color= Color.red))
plot.add(Points(y= [2] * 6, size= 12.0, color= Color.black, fill= fs, outlineColor= Color.black))
plot = Plot()
y1 = [1.5, 1, 6, 5, 2, 8]
cs = [Color.black, Color.red, Color.gray, Color.green, Color.blue, Color.pink]
ss = [StrokeType.SOLID, StrokeType.SOLID, StrokeType.DASH, StrokeType.DOT, StrokeType.DASHDOT, StrokeType.LONGDASH]
plot.add(Stems(y= y1, color= cs, style= ss, width= 5))
plot = Plot(title= "Setting the base of Stems")
ys = [3, 5, 2, 3, 7]
y2s = [2.5, -1.0, 3.5, 2.0, 3.0]
plot.add(Stems(y= ys, width= 2, base= y2s))
plot.add(Points(y= ys))
plot = Plot(title= "Bars")
cs = [Color(255, 0, 0, 128)] * 5 # transparent bars
cs[3] = Color.red # set color of a single bar, solid colored bar
plot.add(Bars(x= [1, 2, 3, 4, 5], y= [3, 5, 2, 3, 7], color= cs, outlineColor= Color.black, width= 0.3))
Explanation: Plot items
Lines, Bars, Points and Right yAxis
End of explanation
plot = Plot(title= "Pandas line")
plot.add(Line(y= tableRows.y1, width= 2, color= Color(216, 154, 54)))
plot.add(Line(y= tableRows.y10, width= 2, color= Color.lightGray))
plot
plot = Plot(title= "Pandas Series")
plot.add(Line(y= pd.Series([0, 6, 1, 5, 2, 4, 3]), width=2))
plot = Plot(title= "Bars")
cs = [Color(255, 0, 0, 128)] * 7 # transparent bars
cs[3] = Color.red # set color of a single bar, solid colored bar
plot.add(Bars(pd.Series([0, 6, 1, 5, 2, 4, 3]), color= cs, outlineColor= Color.black, width= 0.3))
Explanation: Lines,  Points with Pandas
End of explanation
ch = Crosshair(color=Color.black, width=2, style=StrokeType.DOT)
plot = Plot(crosshair=ch)
y1 = [4, 8, 16, 20, 32]
base = [2, 4, 8, 10, 16]
cs = [Color.black, Color.orange, Color.gray, Color.yellow, Color.pink]
ss = [StrokeType.SOLID, 
      StrokeType.SOLID, 
      StrokeType.DASH, 
      StrokeType.DOT, 
      StrokeType.DASHDOT, 
      StrokeType.LONGDASH]
plot.add(Area(y=y1, base=base, color=Color(255, 0, 0, 50)))
plot.add(Stems(y=y1, base=base, color=cs, style=ss, width=5))
plot = Plot()
y = [3, 5, 2, 3]
x0 = [0, 1, 2, 3]
x1 = [3, 4, 5, 8]
plot.add(Area(x= x0, y= y))
plot.add(Area(x= x1, y= y, color= Color(128, 128, 128, 50), interpolation= 0))
p = Plot()
p.add(Line(y= [3, 6, 12, 24], displayName= "Median"))
p.add(Area(y= [4, 8, 16, 32], base= [2, 4, 8, 16],
              color= Color(255, 0, 0, 50), displayName= "Q1 to Q3"))
ch = Crosshair(color= Color(255, 128, 5), width= 2, style= StrokeType.DOT)
pp = Plot(crosshair= ch, omitCheckboxes= True,
                  legendLayout= LegendLayout.HORIZONTAL, legendPosition= LegendPosition.TOP)
x = [1, 4, 6, 8, 10]
y = [3, 6, 4, 5, 9]
pp.add(Line(displayName= "Line", x= x, y= y, width= 3))
pp.add(Bars(displayName= "Bar", x= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], y= [2, 2, 4, 4, 2, 2, 0, 2, 2, 4], width= 0.5))
pp.add(Points(x= x, y= y, size= 10))
Explanation: Areas, Stems and Crosshair
End of explanation
p = Plot ()
p.add(Line(y=[-1, 1]))
p.add(ConstantLine(x=0.65, style=StrokeType.DOT, color=Color.blue))
p.add(ConstantLine(y=0.1, style=StrokeType.DASHDOT, color=Color.blue))
p.add(ConstantLine(x=0.3, y=0.4, color=Color.gray, width=5, showLabel=True))
Plot().add(Line(y=[-3, 1, 3, 4, 5])).add(ConstantBand(x=[1, 2], y=[1, 3]))
p = Plot() 
p.add(Line(x= [-3, 1, 2, 4, 5], y= [4, 2, 6, 1, 5]))
p.add(ConstantBand(x= ['-Infinity', 1], color= Color(128, 128, 128, 50)))
p.add(ConstantBand(x= [1, 2]))
p.add(ConstantBand(x= [4, 'Infinity']))
from decimal import Decimal
pos_inf = Decimal('Infinity')
neg_inf = Decimal('-Infinity')
print (pos_inf)
print (neg_inf)
from beakerx.plot import Text as BeakerxText
plot = Plot()
xs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ys = [8.6, 6.1, 7.4, 2.5, 0.4, 0.0, 0.5, 1.7, 8.4, 1]
def label(i):
  if ys[i] > ys[i+1] and ys[i] > ys[i-1]:
    return "max"
  if ys[i] < ys[i+1] and ys[i] < ys[i-1]:
    return "min"
  if ys[i] > ys[i-1]:
    return "rising"
  if ys[i] < ys[i-1]:
    return "falling"
  return ""
for i in xs:
  i = i - 1
  if i > 0 and i < len(xs)-1:
    plot.add(BeakerxText(x= xs[i], y= ys[i], text= label(i),  pointerAngle= -i/3.0))
plot.add(Line(x= xs, y= ys))
plot.add(Points(x= xs, y= ys))
plot = Plot(title= "Setting 2nd Axis bounds")
ys = [0, 2, 4, 6, 15, 10]
ys2 = [-40, 50, 6, 4, 2, 0]
ys3 = [3, 6, 3, 6, 70, 6]
plot.add(YAxis(label="Spread"))
plot.add(Line(y= ys))
plot.add(Line(y= ys2, yAxis="Spread"))
plot.setXBound([-2, 10])
#plot.setYBound(1, 5)
plot.getYAxes()[0].setBound(1,5)
plot.getYAxes()[1].setBound(3,6)
plot
plot = Plot(title= "Setting 2nd Axis bounds")
ys = [0, 2, 4, 6, 15, 10]
ys2 = [-40, 50, 6, 4, 2, 0]
ys3 = [3, 6, 3, 6, 70, 6]
plot.add(YAxis(label="Spread"))
plot.add(Line(y= ys))
plot.add(Line(y= ys2, yAxis="Spread"))
plot.setXBound([-2, 10])
plot.setYBound(1, 5)
plot
Explanation: Constant Lines, Constant Bands
End of explanation
import time
millis = current_milli_time()
hour = round(1000 * 60 * 60)
xs = []
ys = []
for i in range(11):
    xs.append(millis + hour * i)
    ys.append(i)
plot = TimePlot(timeZone="America/New_York")
# list of milliseconds
plot.add(Points(x=xs, y=ys, size=10, displayName="milliseconds"))
plot = TimePlot()
plot.add(Line(x=tableRows['time'], y=tableRows['m3']))
Explanation: TimePlot
End of explanation
y = pd.Series([7.5, 7.9, 7, 8.7, 8, 8.5])
dates = [np.datetime64('2015-02-01'), 
         np.datetime64('2015-02-02'), 
         np.datetime64('2015-02-03'),
         np.datetime64('2015-02-04'),
         np.datetime64('2015-02-05'),
         np.datetime64('2015-02-06')]
plot = TimePlot()
plot.add(Line(x=dates, y=y))
Explanation: numpy datatime64
End of explanation
y = pd.Series([7.5, 7.9, 7, 8.7, 8, 8.5])
dates = pd.Series(['2015-02-01',
                   '2015-02-02',
                   '2015-02-03',
                   '2015-02-04',
                   '2015-02-05',
                   '2015-02-06']
                  , dtype='datetime64[ns]')
plot = TimePlot()
plot.add(Line(x=dates, y=y))
Explanation: Timestamp
End of explanation
import datetime
y = pd.Series([7.5, 7.9, 7, 8.7, 8, 8.5])
dates = [datetime.date(2015, 2, 1),
         datetime.date(2015, 2, 2),
         datetime.date(2015, 2, 3),
         datetime.date(2015, 2, 4),
         datetime.date(2015, 2, 5),
         datetime.date(2015, 2, 6)]
plot = TimePlot()
plot.add(Line(x=dates, y=y))
import datetime
y = pd.Series([7.5, 7.9, 7, 8.7, 8, 8.5])
dates = [datetime.datetime(2015, 2, 1),
         datetime.datetime(2015, 2, 2),
         datetime.datetime(2015, 2, 3),
         datetime.datetime(2015, 2, 4),
         datetime.datetime(2015, 2, 5),
         datetime.datetime(2015, 2, 6)]
plot = TimePlot()
plot.add(Line(x=dates, y=y))
Explanation: Datetime and date
End of explanation
millis = current_milli_time()
nanos  = millis * 1000 * 1000
xs = []
ys = []
for i in range(11):
    xs.append(nanos + 7 * i)
    ys.append(i)
nanoplot = NanoPlot()
nanoplot.add(Points(x=xs, y=ys))
Explanation: NanoPlot
End of explanation
y1 = [1,5,3,2,3]
y2 = [7,2,4,1,3]
p = Plot(title='Plot with XYStacker', initHeight=200)
a1 = Area(y=y1, displayName='y1')
a2 = Area(y=y2, displayName='y2')
stacker = XYStacker()
p.add(stacker.stack([a1, a2]))
Explanation: Stacking
End of explanation
SimpleTimePlot(tableRows, ["y1", "y10"], # column names
               timeColumn="time", # time is default value for a timeColumn
               yLabel="Price", 
               displayNames=["1 Year", "10 Year"],
               colors = [[216, 154, 54], Color.lightGray],
               displayLines=True, # no lines (true by default)
               displayPoints=False) # show points (false by default))
#time column base on DataFrame index 
tableRows.index = tableRows['time']
SimpleTimePlot(tableRows, ['m3'])
rng = pd.date_range('1/1/2011', periods=72, freq='H')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
df = pd.DataFrame(ts, columns=['y'])
SimpleTimePlot(df, ['y'])
Explanation: SimpleTime Plot
End of explanation
p = TimePlot(xLabel= "Time", yLabel= "Interest Rates")
p.add(YAxis(label= "Spread", upperMargin= 4))
p.add(Area(x= tableRows.time, y= tableRows.spread, displayName= "Spread",
              yAxis= "Spread", color= Color(180, 50, 50, 128)))
p.add(Line(x= tableRows.time, y= tableRows.m3, displayName= "3 Month"))
p.add(Line(x= tableRows.time, y= tableRows.y10, displayName= "10 Year"))
Explanation: Second Y Axis
The plot can have two y-axes. Just add a YAxis to the plot object, and specify its label.
Then for data that should be scaled according to this second axis,
specify the property yAxis with a value that coincides with the label given.
You can use upperMargin and lowerMargin to restrict the range of the data leaving more white, perhaps for the data on the other axis.
End of explanation
import math
points = 100
logBase = 10
expys = []
xs = []
for i in range(0, points):
  xs.append(i / 15.0)
  expys.append(math.exp(xs[i]))
cplot = CombinedPlot(xLabel= "Linear")
logYPlot = Plot(title= "Linear x, Log y", yLabel= "Log", logY= True, yLogBase= logBase)
logYPlot.add(Line(x= xs, y= expys, displayName= "f(x) = exp(x)"))
logYPlot.add(Line(x= xs, y= xs, displayName= "g(x) = x"))
cplot.add(logYPlot, 4)
linearYPlot = Plot(title= "Linear x, Linear y", yLabel= "Linear")
linearYPlot.add(Line(x= xs, y= expys, displayName= "f(x) = exp(x)"))
linearYPlot.add(Line(x= xs, y= xs, displayName= "g(x) = x"))
cplot.add(linearYPlot,4)
cplot
plot = Plot(title= "Log x, Log y", xLabel= "Log", yLabel= "Log",
                    logX= True, xLogBase= logBase, logY= True, yLogBase= logBase)
plot.add(Line(x= xs, y= expys, displayName= "f(x) = exp(x)"))
plot.add(Line(x= xs, y= xs, displayName= "f(x) = x"))
plot
Explanation: Combined Plot
End of explanation
<END_TASK>