Bokeh and how to make it into a GUI - python

I am writing in python and have all my functionalities for analyzing datasets. Now, I would like to turn these functions into a user-ready application that, in a sense, works like an .exe app. In bokeh, I saw that you could create a plot, table...etc; however, is it possible to create a GUI where you can:
upload a file for analysis
load functions from my written python to analyze the uploaded file
graph the results onto a graph
click different buttons that can take you to different (so-called) pages so that you can perform different functions.
basically it can go from one page to the other kind of like a webpage where you click one button it links you to the next page for another purpose and home to go back. Could you potentially do this with bokeh?

There are several examples of data web applications created using Bokeh at demo.bokeh.org. Here is one modeled after the "Shiny Movie Explorer", but written in pure Python/Bokeh (instead of R/Shiny).
You can find much more details about creating and deploying Bokeh applications in the Running a Bokeh Server chapter of the docs.
Here is a complete (but simpler) example that demonstrates the basic gist and structure:
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
# Set up data
x = np.linspace(0, 4*np.pi, 200)
y = np.sin(x)
source = ColumnDataSource(data=dict(x=x, y=y))
# Set up plot
plot = figure(title="my sine wave")
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)
# Set up widgets
freq = Slider(title="frequency", value=1.0, start=0.1, end=5.1, step=0.1)
# Set up callbacks
def update_data(attrname, old, new):
# Get the current slider values and set new data
k = freq.value
x = np.linspace(0, 4*np.pi, 200)
y = np.sin(k*x)
source.data = dict(x=x, y=y)
freq.on_change('value', update_data)
# Set up layouts and add to document
curdoc().add_root(column(freq, plot))
curdoc().title = "Sliders"
To run this locally you'd execute:
bokeh serve --show myscript.py
For more sophisticated deployments (i.e. with proxies) or to embed directly in e.g. Flask, see the docs.

Related

Control the Bokeh xwheel_zoom tool using a Bokeh widget/callback

I am using xwheel_zoom (WheelZoomTool) for a Bokeh chart with datetime axis.
p = figure(x_axis_type="datetime", tools='xwheel_zoom, crosshair, undo, reset')
I provide pandas TimeStamp as the x value of this chart. For example:pd.Timestamp.now(tz='utc'). The x axis range of this chart is for the last 24 hours.
start = pd.Timestamp.now(tz='utc') - pd.Timedelta(hours=24)
Using xwheel_zoom, I could zoom in to see my chart better for a given time (e.g. last hour).
Is there any way in Bokeh I could achieve this zoom functionality by coding or connecting to the xwheel_zoom and controling it with a Bokeh widget (e.g. Bokeh dropdown)?
My objective is to have a button to click on and let it show me the zoomed in x_axis for the last hour, or show the chart between a datetime period I define. Idealy, I do not want to re-define/re-draw the chart again and just want to control the xwheel_zoom functionality.
You don't need any tools to do that. Just change the desired range in a callback. Something like:
b = Button()
def update():
p.x_range.update(start=0, end=1)
b.on_click(update)
The example will work only if used with bokeh serve. If you're not using that, you can rewrite the code to work with CustomJS and js_on_click.

How best to create a simple, interactive, shareable plot with python?

I'm hoping someone can point me in the right direction. The python datavis landscape has now become huge and there are so many options that I'm a bit lost on what the best way to achieve this is.
I have an xarray dataset (but it could easily be a pandas dataframe or a list of numpy arrays).
I have 3 columns, A, B, and C. They contain 40 data points.
I want to plot a scatter plot of A vs B + scale*C where scale is determined from an interactive slider.
The more advanced version of this would have a dropdown where you can select a different set of 3 columns but I'll worry about that bit later.
The caveat on all of this is that I'd like it to be online and interactive for others to use.
There seem to be so many options:
Jupyter (I don't use notebooks so I'm not that familiar with them but
with mybinder I assume this is easy to do)
Plotly
Bokeh Server
pyviz.org (this is the really interesting one but again, there'd seem
to be so many options on how to accomplish this)
Any thoughts or advice would be much appreciated.
There are indeed many options and i'm not sure what is best but i use bokeh a lot and am happy about it. The example below can get you started. To launch this open a cmd in the directory where you save the script and run "bokeh serve script.py --show --allow-websocket-origin=*".
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.models.widgets import Slider
from bokeh.models import Row,ColumnDataSource
#create the starting data
x=[0,1,2,3,4,5,6,7,8]
y_noise=[1,2,2.5,3,3.5,6,5,7,8]
slope=1 #set the starting value of the slope
intercept=0 #set the line to go through 0, you can change this later
y= [slope*i + intercept for i in x]#create the y data via a list comprehension
# create a plot
fig=figure() #create a figure
source=ColumnDataSource(dict(x=x, y=y)) #the data destined for the figure
fig.circle(x,y_noise)#add some datapoints to the plot
fig.line('x','y',source=source,color='red')#add a line to the figure
#create a slider and update the graph source data when it changes
def updateSlope(attrname, old, new):
print(str(new)+" is the new slider value")
y = [float(new)*i + intercept for i in x]
source.data = dict(x=x, y=y)
slider = Slider(title="slope", value=slope, start=0.0, end=2.0,step=0.1)
slider.on_change('value', updateSlope)
layout=Row(fig,slider)#put figure and slider next to eachother
curdoc().add_root(layout)#serve it via "bokeh serve slider.py --show --allow-websocket-origin=*"
The allow-websocket-origin=* is to allow other users to reach out to the server and see the graph. The http would be http://yourPCservername:5006/ (5006 is the default bokeh port). If you don't want to serve from your PC you can subscribe to a cloud service like Heroku: example.

Embedding matplotlib moving chart in django template

I am new to python Django framework.
I have matplotlib moving or live chart, It should be embedded in django template. I checked many question relevant to this here but none of them is worked for me. Most of us suggested here is displaying as image, but problem is moving chart with default interface like zoom, drag everything to be integrated.
i am struggling to solve . I used this code and got to know it will be displaying as image.
def simple(request):
import random
import django
import datetime
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.dates import DateFormatter
fig = Figure()
ax = fig.add_subplot(111)
x = []
y = []
now = datetime.datetime.now()
delta = datetime.timedelta(days=1)
for i in range(10):
x.append(now)
now += delta
y.append(random.randint(0, 1000))
ax.plot_date(x, y, '-')
ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
fig.autofmt_xdate()
canvas = FigureCanvas(fig)
response = django.http.HttpResponse(content_type='image/png')
canvas.print_png(response)
return response
I used this code for reference.
if this is not understandable please comment below, ill try to convey you clearly
can any one help me to get fixed this. Thanks in advance.
Instead of doing with matplotlib you can try with BOKEH chart. check this out Bokeh charts doc
While it may seem like a simple question, the machinery that matplotlib employs to present an interactive chart on desktop is reasonably complex, and not something one can just drop in to some HTML somewhere.
I would suggest you look at a frontend library for graphically displaying data, then provide your frontend the data with your backend.
As for libraries, check out C3. It's got good docs and examples.

Bokeh time plotting

I am experimenting with time plots such as this example from bokeh. Is it possible to create minor ticks for the x-axis? I tried all the different options inside p.xaxis.minor but none seemed useful.
Here's the code from example:
import pandas as pd
from bokeh.plotting import figure, output_file, show
AAPL = pd.read_csv(
"http://ichart.yahoo.com/table.csv?s=AAPL&a=0&b=1&c=2000&d=0&e=1&f=2010",
parse_dates=['Date']
)
output_file("datetime.html")
# create a new plot with a datetime axis type
p = figure(width=800, height=250, x_axis_type="datetime")
p.line(AAPL['Date'], AAPL['Close'], color='navy', alpha=0.5)
show(p)
And the image:
From what it seems it's automatically turned off, and the x-axis updates properly as you zoom in, but it would be great to include minor ticks for visualization purpose.
As of Bokeh 0.10, the BokehJS DatetimeTicker sets num_minor_ticks to zero on the internal tickers that it uses:
https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/ticking/datetime_ticker.coffee#L23
There is currently no simple way exposed to override this (You could write some JavaScript to reach in directly, but that would be a pain). I am not sure if this state of affairs is due to some inherent problem with minor ticks and datatime ranges, or if this was merely an oversight. Please make a new issue on the Bokeh GH issue tracker so it can be investigated:
https://github.com/bokeh/bokeh/issues

How to save a bokeh gridplot as single file

I am using bokeh (0.8.1) in combination with the ipython notebook to generate GridPlots. I would like to automatically store the generated GridPlots to a single png (hopefully pdf one day) on disk, but when using "Preview/Save" it cycles through all of the figures asking me to store them separately. Is there a more efficient way?
You can export plot layouts in the same manner that you can export individual plots:
from bokeh.io import export_png
from bokeh.layouts import gridplot
plots = gridplot([[plot_1, plot_2], [plot_3, plot_4]])
export_png(plots, filename='./path/to/file.png')
Note that there are additional dependencies per bokeh documentation:
The selenium python library
A headless browser and driver (eg chromium and chromedriver)
First you save your grid in an object,
Let's say "a" the you confirms that "a" is a grid. Example
grid = bly.gridplot(graficas,ncols=3) # Here you save your grid
bpl.show(grid). # Here you show your grid
from bokeh.io import export_png # You need this library to export
Exportar grid
export_png(grid, filename="your path/name.png")

Categories

Resources