dropdown button to interact with a graph using jupyter bokeh by changing the y and x axis - python-3.x

I am fairly new to bokeh(using jupyter) and I was trying to create a simple line and scatter graph with a drop-down button where I could select a set of values for x-axis and y-axis and see them being updated in real time but for some reason for the graph does not get updated correctly this is a portion of my code:
weight= [23,45,11,40]
velocity= [12,65,32,15]
momentum = [12,78,22,40]
p = figure(plot_height=300,plot_width=500,title="Graph line of DATA")
p.title.text_font_style = "bold"
r = p.line(weight,velocity, color="red", line_width=3)
tab1=Panel(child=p, title="line")
p1 = figure(plot_height=300,plot_width=500,title="Graph line of DATA")
r1 = p1.circle(weight,velocity, size=10, color="red", alpha=0.5)
p1.title.text_font_style = "bold"
tab2=Panel(child=p1, title="Circle")
def updatex(Xaxis):
if Xaxis == "Weight":
func = weight
p.xaxis.axis_label = "pounds"
p1.xaxis.axis_label = "pounds"
elif Xaxis == "Velocity":
func = velocity
p.xaxis.axis_label = "m/s"
p1.xaxis.axis_label = "m/s"
elif Xaxis == "Momemtum":
func = momentum
p.xaxis.axis_label = "lb-sec"
p1.xaxis.axis_label = "lb-sec"
r.data_source.data['x'] = func
r1.data_source.data['x'] = func
push_notebook()
def updatey(Yaxis):
if Yaxis == "Weight":
func = weight
p.xaxis.axis_label = "pounds"
p1.xaxis.axis_label = "pounds"
elif Yaxis == "Velocity":
func = velocity
p.xaxis.axis_label = "m/s"
p1.xaxis.axis_label = "m/s"
elif Xaxis == "Momemtum":
func = momentum
p.xaxis.axis_label = "lb-sec"
p1.xaxis.axis_label = "lb-sec"
r.data_source.data['y'] = func
r1.data_source.data['y'] = func
push_notebook()
# the following snippet would be in the following cell below:
interact(updatex,Xaxis=["Weight", "Velocity", "Momemtum"])
interact(updatey,Yaxis=["Weight","Velocity","Momemtum"])

Related

How to change color of mark on topoplot interactively?

I want to create interactive line- and topoplot depending on menu. I figured out how to make red the line chosen in menu, but it doesn't work for topoplot marks (black circles inside topoplot). I can change it manually (cmap[][4] = RGB{N0f8}(1.0,0.0,0.0)), but how to do that interactively?
f = Figure(backgroundcolor = RGBf(0.98, 0.98, 0.98), resolution = (1500, 700))
ax = Axis(f[1:3, 1], xlabel = "Time [s]", ylabel = "Voltage amplitude [µV]")
N = 1:length(pos) #1:4
hidespines!(ax, :t, :r)
GLMakie.xlims!(-0.3, 1.2)
hlines!(0, color = :gray, linewidth = 1)
vlines!(0, color = :gray, linewidth = 1)
times = range(-0.3, length=size(dat_e,2), step=1 ./ 128)
lines = Dict()
for i in N
mean_trial = mean(dat_e[i,:,:],dims=2)[:,1]
line = lines!(times, mean_trial, color = "black")
lines[i] = line
end
hidedecorations!(ax, label = false, ticks = false, ticklabels = false)
topo_axis = Axis(f[2, 2], width = 178, height = 178, aspect = DataAspect())
Makie.xlims!(low = -0.2, high = 1.2)
Makie.ylims!(low = -0.2, high = 1.2)
topoMatrix = eegHeadMatrix(pos[N], (0.5, 0.5), 0.5)
cmap = Observable(collect(ColorScheme(range(colorant"black", colorant"black", length=30))))
#cmap[][4] = RGB{N0f8}(1.0,0.0,0.0)
topo = eeg_topoplot!(topo_axis, N, # averaging all trial of 30 participants on Xth msec
raw.ch_names[1:30];
positions=pos, # produced automatically from ch_names
interpolation=NullInterpolator(),
enlarge=1,
#colorrange = (0, 1), # add the 0 for the white-first color
colormap = cmap[],
label_text=false)
hidedecorations!(current_axis())
hidespines!(current_axis())
num_prev = 0
menu = Menu(f[3, 2], options = raw.ch_names[1:30], default = nothing)#, default = "second")
on(menu.selection) do selected
if selected != nothing
num = findall(x->x==menu.selection[], raw.ch_names[1:30])[]
if num_prev != 0
lines[num_prev].color = "black"
cmap[][num] = RGB{N0f8}(1.0,0.0,0.0)
end
lines[num].color = "red"
cmap[][num] = RGB{N0f8}(1.0,0.0,0.0)
num_prev = num
end
end
notify(menu.selection)
#print(cmap[])
f
We solved this by putting this string at the end of the menu.selection section:
notify(lines)
It works, because lines() automatically creates Observable.

Plotly plot a vertical line on a time series plot due to conditions

Hi I have a dataframe with time series on my x axis and values on my y axis.
I am using Plotly and am trying to plot a vertical line on the x axis where there my df.Alert == 1.
Currently I am using another overlay with red marker to plot it but I wish to switch to a vertical line that is restricted within by the y values of my chart. The values on the y axis should still be determined by my trace plot and not the vertical line.
Is there a way for me to do this?
My code sample is written below
Trace = go.Scatter(
name = "Values",
x = df.DateTime,
y = df.Values,
mode='markers',
text= "Unit: " + df['Unit'].astype(str),
)
Alert = go.Scatter(
name = "Alert",
x = df.DateTime,
y = df.Values.where(df.Alert == 1),
mode='markers',
line = dict(color = "red"),
text= "Unit: " + df['Unit'].astype(str),
)
layout = go.Layout(
xaxis = dict(title = "Date and Time"),
yaxis = dict(title = "Values")
)
data = [Trace, Alert]
figure = go.Figure(data = data, layout = layout)
py.iplot(figure)
You perfectly describe what you want to do... plot vline
iterate over rows in DF that are alerts fig.add_vline()
n=50
df = pd.DataFrame({"DateTime":pd.date_range("1-jan-2021", freq="15min", periods=n),
"Alert":np.random.choice([0]*10+[1], n),
"Unit":np.random.choice([0,1,2,3], n),
"Values":np.random.uniform(1,10, n)})
Trace = go.Scatter(
name = "Values",
x = df.DateTime.astype(str),
y = df.Values,
mode='markers',
text= "Unit: " + df['Unit'].astype(str),
)
layout = go.Layout(
xaxis = dict(title = "Date and Time"),
yaxis = dict(title = "Values")
)
data = [Trace]
figure = go.Figure(data = data, layout = layout)
for r in df.loc[df.Alert.astype(bool),].iterrows():
figure.add_vline(x=r[1]["DateTime"], line_width=1, line_dash="solid", line_color="red")
figure

AttributeError: 'list' object has no attribute 'get_zorder'

I'm trying to animate projectile motion with the help of matplotlib.animation but I've been facing a few errors. Please help me with this.
Thank you so much
I've tried searching through the internet and I did implement solutions of a few similar problems but the code still gives an error
import matplotlib as mat
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as mat_anim
u = 5
g = 9.8
theta_degree = np.rad2deg([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
theta_rad = [0, np.pi/6, np.pi/4, np.pi/3, np.pi/2]
fr = 100
print(1)
def projectile_range():
# calculate projectile range
rng = ((u**2)*(np.sin(np.multiply(2.0, theta_rad))))/g
return rng
def max_height():
# calculate maximum height of projectile
max_ht = ((u*np.sin(theta_rad))**2)/(2*g)
return max_ht
def projectile():
# calculating projectile path
r = projectile_range()
for j in range(len(r)):
x = np.linspace(0, r[j], 100)
y.append(x*(np.tan(theta_rad[j])) - ((0.5*g*(x**2))/(u*np.cos(theta_rad[j]))**2))
return y
fig1, ax1 = plt.subplots(1,1)
fig1.suptitle("Projectile Motion Range", fontsize = 10)
ax1.set_xlim([0, round(max(projectile_range()))+1])
ax1.set_ylim([0, round(max(max_height()))+1])
# ax_range, = ax1.plot([], [])
dots, = ax1.plot([], [], 'o')
lines, = ax1.plot([], [], lw = 2)
plot_colour = ["black", "red", "green", "yellow", "blue"]
line_list = []
dot_list = []
print(2)
for index in range(len(theta_rad)):
line_obj = ax1.plot([], [], lw = 2, color = plot_colour[index])[0]
dot_obj = ax1.plot([], [], 'o', color = plot_colour[len(theta_rad)-index-1])[0]
line_list.append(line_obj)
dot_list.append(dot_obj)
print(3)
def initialize():
# initializing projectile range plot
print(4)
for line in line_list:
line.set_data([], [])
for dot in dot_list:
dot.set_data([], [])
print(5)
return dot_list, line_list,
print(6)
def proj_animation(i):
# animation function
print(7)
n = 100
# fr = n
y = np.empty([len(theta_rad), n], dtype = float)
x = np.empty([len(theta_rad), n], dtype = float)
r = projectile_range()
for j in range(len(r)):
x[j] = np.linspace(0, r[j], n)
y[j] = np.multiply(x[j], np.tan(theta_rad[j])) - ((0.5*g*(np.square(x[j])))/(u*np.cos(theta_rad[j]))**2)
for count, element in enumerate(line_list):
element.set_data(x[count][:i], y[count][:i])
for count, element in enumerate(dot_list):
element.set_data(x[count][i], y[count][i])
print(8)
return dot_list,line_list,
proj_anim = mat_anim.FuncAnimation(fig1, proj_animation, frames = fr,
interval = 20, blit = True)
proj_anim.save("projectile_range.mp4", fps = 20, extra_args = ['-vcodec', 'libx264'])
plt.show()
key=lambda x: x.get_zorder())
AttributeError: 'list' object has no attribute 'get_zorder'
I believe the issue is that in proj_animation() you are returning a tuple of two lists, but FuncAnimation() is looking for an iterable of drawn objects directly. The quickest fix for this is to concatenate dot_list with line_list and return the concatenated list. Nb This should also be done in your initialization function.
I was trying to plot sensor data using subplots and was getting the same error. The way I fixed it was to return just a variable or a list. In the animation function I was returning a list of lists, I just flattened this list of lists and the code works. The solution adapted to your code is the following:
import matplotlib as mat
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as mat_anim
u = 5
g = 9.8
theta_degree = np.rad2deg([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
theta_rad = [0, np.pi/6, np.pi/4, np.pi/3, np.pi/2]
fr = 100
print(1)
def projectile_range():
# calculate projectile range
rng = ((u**2)*(np.sin(np.multiply(2.0, theta_rad))))/g
return rng
def max_height():
# calculate maximum height of projectile
max_ht = ((u*np.sin(theta_rad))**2)/(2*g)
return max_ht
def projectile():
# calculating projectile path
r = projectile_range()
for j in range(len(r)):
x = np.linspace(0, r[j], 100)
y.append(x*(np.tan(theta_rad[j])) - ((0.5*g*(x**2))/(u*np.cos(theta_rad[j]))**2))
return y
fig1, ax1 = plt.subplots(1,1)
fig1.suptitle("Projectile Motion Range", fontsize = 10)
ax1.set_xlim([0, round(max(projectile_range()))+1])
ax1.set_ylim([0, round(max(max_height()))+1])
# ax_range, = ax1.plot([], [])
dots, = ax1.plot([], [], 'o')
lines, = ax1.plot([], [], lw = 2)
plot_colour = ["black", "red", "green", "yellow", "blue"]
line_list = []
dot_list = []
print(2)
for index in range(len(theta_rad)):
line_obj = ax1.plot([], [], lw = 2, color = plot_colour[index])[0]
dot_obj = ax1.plot([], [], 'o', color = plot_colour[len(theta_rad)-index-1])[0]
line_list.append(line_obj)
dot_list.append(dot_obj)
print(3)
def initialize():
# initializing projectile range plot
print(4)
for line in line_list:
line.set_data([], [])
for dot in dot_list:
dot.set_data([], [])
print(5)
return dot_list, line_list,
print(6)
def proj_animation(i):
# animation function
print(7)
n = 100
# fr = n
y = np.empty([len(theta_rad), n], dtype = float)
x = np.empty([len(theta_rad), n], dtype = float)
r = projectile_range()
graph_list = []
for j in range(len(r)):
x[j] = np.linspace(0, r[j], n)
y[j] = np.multiply(x[j], np.tan(theta_rad[j])) - ((0.5*g*(np.square(x[j])))/(u*np.cos(theta_rad[j]))**2)
for count, element in enumerate(line_list):
element.set_data(x[count][:i], y[count][:i])
for count, element in enumerate(dot_list):
element.set_data(x[count][i], y[count][i])
graph_list.append(dot_list)
graph_list.append(line_list)
graph_list = [item for sublist in graph_list for item in sublist]
print(8)
return graph_list
proj_anim = mat_anim.FuncAnimation(fig1, proj_animation, frames = fr,
interval = 20, blit = True)
proj_anim.save("projectile_range.mp4", fps = 20, extra_args = ['-vcodec', 'libx264'])
plt.show()
I test the code and it works.

plotly: 3D plotting returns a figure with no datapoints

Trying to plot results from K-means clustering using 3D plot (Plotly). There is a blank figure generated in the HTML when I use the below code. I printed the variables scatter 1,2,3 and also the cluster 1,2,3 and values are shown. Is there a plt.show() like in matplotlib in plotly to show the values in the graph?
import pandas as pd
import numpy as np
import argparse
import json
import re
import os
import sys
import plotly
import plotly.graph_objs as go
cluster1=df.loc[df['y'] == 0]
cluster2=df.loc[df['y'] == 1]
cluster3=df.loc[df['y'] == 2]
scatter1 = dict(
mode = "markers",
name = "Cluster 1",
type = "scatter3d",
x = cluster1.as_matrix()[:,0], y = cluster1.as_matrix()[:,1], z = cluster1.as_matrix()[:,2],
marker = dict( size=2, color='green')
)
scatter2 = dict(
mode = "markers",
name = "Cluster 2",
type = "scatter3d",
x = cluster2.as_matrix()[:,0], y = cluster2.as_matrix()[:,1], z = cluster2.as_matrix()[:,2],
marker = dict( size=2, color='blue')
)
scatter3 = dict(
mode = "markers",
name = "Cluster 3",
type = "scatter3d",
x = cluster3.as_matrix()[:,0], y = cluster3.as_matrix()[:,1], z = cluster3.as_matrix()[:,2],
marker = dict( size=2, color='red')
)
cluster1 = dict(
alphahull = 5,
name = "Cluster 1",
opacity = .1,
type = "mesh3d",
x = cluster1.as_matrix()[:,0], y = cluster1.as_matrix()[:,1], z = cluster1.as_matrix()[:,2],
color='green', showscale = True
)
cluster2 = dict(
alphahull = 5,
name = "Cluster 2",
opacity = .1,
type = "mesh3d",
x = cluster2.as_matrix()[:,0], y = cluster2.as_matrix()[:,1], z = cluster2.as_matrix()[:,2],
color='blue', showscale = True
)
cluster3 = dict(
alphahull = 5,
name = "Cluster 3",
opacity = .1,
type = "mesh3d",
x = cluster3.as_matrix()[:,0], y = cluster3.as_matrix()[:,1], z = cluster3.as_matrix()[:,2],
color='red', showscale = True
)
layout = dict(
title = 'Interactive Cluster Shapes in 3D',
scene = dict(
xaxis = dict(zeroline=True ),
yaxis = dict(zeroline=True ),
zaxis = dict(zeroline=True ),
)
)
fig = dict(data=[scatter1, scatter2, scatter3, cluster1, cluster2, cluster3], layout=layout )
# Use py.iplot() for IPython notebook
plotly.offline.iplot(fig, filename='mesh3d_sample.html')
#py.iplot(fig, filename='mesh3d_sample')
HTML with just the axis and no data points displayed

Bokeh charts unresponsive on rangeslider on_change

I am working on bokeh charts for the first time. I have followed a few tutorials but due to some reason, update function is not working on rangeslider on_change()
def make_data(df, start, end):
#df['ID'] = range(1, len(df) + 1)
s = df['ID'] >= start
e = df['ID'] <= end
df1 = df[e & s]
date = df1['date'].tolist()
capi = df1['capi'].tolist()
data = {'x': dateTime(date), 'y': capi}
source = ColumnDataSource(data)
return source
def update(attr, old, new):
df = pd.DataFrame.from_csv("main_data.csv", index_col = None)
df['ID'] = range(1, len(df) + 1)
new_src = make_dataset(df, range_start = range_select.value[0], range_end = range_select.value[1])
source.data.update(new_src.data)
def make_plot(source):
p1 = figure(x_axis_type="datetime", title="Stock Closing Prices")
p1.grid.grid_line_alpha=0.3
p1.xaxis.axis_label = 'Date'
p1.yaxis.axis_label = 'Price'
p1.line('x', 'y', source = source, color='#A6CEE3', legend='capi')
return p1
range_select = RangeSlider(title="Date range", value=(ids[0], ids[100]), start=ids[0], end=ids[-1], step=1)
range_select.on_change('value', update)
source = make_data(df, 1, 1000)
p = make_plot(source)
controls = WidgetBox(range_select)
layout = column(controls, p)
tab = Panel(child=layout, title = 'Histogram')
tabs = Tabs(tabs = [tab])
show(tabs)
can someone please point me in the right direction here

Resources