Modify styling options for holoviews sankey graph - holoviews

Is it possible to modify Node style in a holoviews (v 1.10.4) Sankey diagram backed by bokeh (v 0.12.16)? I am setting the node_line_color using the options method (also tried via %%opts in Jupiter notebook) however it is ignored and I see a black outline (default) instead of the white I specify. Only the node_width attribute seems to work but all other node styling attributes are ignored.
import pandas as pd
import holoviews as hv
hv.extension('bokeh')
edges = pd.read_csv('data.csv')
hv.Sankey(edges).options(node_line_color='white')

The docs are horrible, but I've discovered you probably want to do this:
sankey = hv.Sankey(edges)
sankey.opts(label_position='left', node_width=30)

Related

Does Hovertool/tooltip work with pandas df or only with ColumnDataSource

Pretty new to Bokeh. Plotting a barplot (after importing pandas_bokey) works well.
But... I want to change the hoover tooltips.
Question: should hoover tooltip work with a pandas df in Bokeh or must ColumnDataSource be used?
thanks
One option in pandas_bokeh to modify the HoverTool is passing a custom string to hovertool_string.
import pandas as pd
import pandas_bokeh
from bokeh.plotting import output_notebook
output_notebook()
df = pd.DataFrame({'a':[1,2], 'b':[3,4]})
df.plot_bokeh.bar(hovertool_string=r"""At index #{__x__values}: a is #{a} and b is #{b}""")
default output
modified tooltop
To see a more complex example check the 2. example in the line plot documentation
Comment
Because your question is very open, I am not sure if the answer is satisfying. Please provide some Minimal Working Example and some example data in future.

Axis_type="mercator" in bokeh

I'm trying to run the chart given as example for Tile Provider Maps on the Bokeh geo-mapping site.
https://docs.bokeh.org/en/latest/docs/user_guide/geo.html.
from bokeh.plotting import figure, show, output_file
from bokeh.tile_providers import CARTODBPOSITRON
output_file("tile.html")
# range bounds supplied in web mercator coordinates
p = figure(x_range=(-2000000, 6000000), y_range=(-1000000, 7000000),
x_axis_type="mercator", y_axis_type="mercator")
p.add_tile(CARTODBPOSITRON)
show(p)
But instead of the expected chart I'm getting:
ValueError: expected an element of either Auto or Enum('linear', 'log', 'datetime'), got 'mercator'
If I delete the x_axis_type paremeters (x_axis_type="mercator", y_axis_type="mercator") I'm getting the chart, though as expected, without latitude and longitute labels. Is there a problem in the script or am I doing something wrong here?
Your version of Bokeh is too old, you will have to update to at least version 0.12.15 to use this feature

Can I draw an annotation in bokeh with data from a ColumnDataSource?

I'd like to draw a vertical line on my Bokeh plot which gets moved around by javascript in the browser at runtime. (It's a timebar that marks the current time on a time series plot.)
For drawing a static vertical line, I'm using:
from bokeh.models import Span
timebar = Span(location=where_I_want_the_timebar, dimension=height)
my_figure.add_layout(timebar)
In order to enable the interactivity, I think I need to get the location from a ColumnDataSource. However, I can't figure out how to do that, because Span does not accept a source argument.
Alternatively, is there another way for me to move the timebar at runtime?
I found a workaround. In python:
from bokeh.models import Span
timebar = Span(name='timebar' location=where_I_want_the_timebar, dimension=height)
my_figure.add_layout(timebar)
Then in javascript in the browser:
let timebar = Bokeh.documents[0].get_model_by_name('timebar')
timebar.attributes.location = my_new_desired_location
timebar.change.emit()
If someone posts a way to use a ColumnDataSource I will accept that answer.

Unable to set bokeh plotting parameters using BOKEH + HOLOVIEW plotting option via Python

Is there any documentation specifying how to pass Bokeh parameters via holoview?
I am reading the tutorials but I think there is something small I have missed.
There is an example online which describes this in Ipython but I am trying to do it via a python WITHOUT Ipython notebook.
http://holoviews.org/Tutorials/Bokeh_Backend.html?highlight=bokeh
When I run this program I get the curves but the color does not change and I also get this error: WARNING:root:Curve01537: Setting non-parameter attribute style={'line_color': 'green'} using a mechanism intended only for parameters
How can we set the parameter?
Code Example here
from pprint import pprint, pformat
import holoviews as hv
import numpy as np
import pathlib, os
import webbrowser
import lasio, las
from holoviews import Store
from holoviews.plotting.bokeh.element import (line_properties, fill_properties, text_properties)
def plot_bokeh(plot):
#Create renderer instance
myrenderer = hv.Store.renderers['bokeh'].instance(fig='html')
out_file_name = "".join(["./OUTPUT/","gyro", "_graph.html"])
with open (out_file_name, 'w') as f:
#Plot static html
f.write (myrenderer.static_html(plot))
f.close()
webbrowser.open_new_tab(pathlib.Path(os.path.abspath(out_file_name)).as_uri())
def holoview_sandbox():
curve_opts = dict(line_color='green')
xs = np.linspace(0, np.pi*4, 100)
data = (xs, np.sin(xs))
holo_plot = hv.Curve(data, label='MY LABEL' , style=curve_opts)
plot_bokeh(holo_plot)
if __name__ == '__main__':
holoview_sandbox()
In HoloViews the options aren't bound to the objects themselves, which has various benefits including being able to plot with different backends. The pure-Python way of setting style options is this:
curve_opts = dict(line_color='green')
xs = np.linspace(0, np.pi*4, 100)
data = (xs, np.sin(xs))
holo_plot = hv.Curve(data, label='MY LABEL')(style=curve_opts)
The Options Tutorial describes how to set options like this, but please let us know if you found some of that unclear.
This syntax works as well
holo_plot.opts(style={'color': 'green'})
When you change the entry 'line_color' to 'color' in the dict() of Philipp's answer, then this works for the matplotlib backend as well.
Details about setting options can also be found here in addition to Philipp's link.

Animated graphs in ipython notebook

Is there a way of creating animated graphs. For example showing the same graph, with different parameters.
For example is SAGE notebook, one can write:
a = animate([circle((i,i), 1-1/(i+1), hue=i/10) for i in srange(0,2,0.2)],
xmin=0,ymin=0,xmax=2,ymax=2,figsize=[2,2])
a.show()
This has horrible flickering, but at least this creates a plot that animates for me. It is based on Aron's, but Aron's does not work as-is.
import time, sys
from IPython.core.display import clear_output
f, ax = plt.subplots()
n = 30
x = array([i/10.0 for i in range(n)])
y = array([sin(i) for i in x])
for i in range(5,n):
ax.plot(x[:i],y[:i])
time.sleep(0.1)
clear_output()
display(f)
ax.cla() # turn this off if you'd like to "build up" plots
plt.close()
Update: January 2014
Jake Vanderplas has created a Javascript-based package for matplotlib animations available here. Using it is as simple as:
# https://github.com/jakevdp/JSAnimation
from JSAnimation import examples
examples.basic_animation()
See his blog post for a more complete description and examples.
Historical answer (see goger for a correction)
Yes, the Javascript update does not correctly hold the image frame yet, so there is flicker, but you can do something quite simple using this technique:
import time, sys
from IPython.display import clear_output
f, ax = plt.subplots()
for i in range(10):
y = i/10*sin(x)
ax.plot(x,y)
time.sleep(0.5)
clear_output()
display(f)
ax.cla() # turn this off if you'd like to "build up" plots
plt.close()
IPython widgets let you manipulate Python objects in the kernel with GUI objects in the Notebook. You might also like Sage hosted IPython Notebooks. One problem you might have with sharing widgets or interactivity in Notebooks is that if someone else doesn't have IPython, they can't run your work. To solve that, you can use Domino to share Notebooks with widgets that others can run.
Below are three examples of widgets you can build in a Notebook using pandas to filter data, fractals, and a slider for a 3D plot. Learn more and see the code and Notebooks here.
If you want to live-stream data or set up a simulation to run as a loop, you can also stream data into plots in a Notebook. Disclaimer: I work for Plotly.
If you use IPython notebook, v2.0 and above support interactive widgets. You can find a good example notebook here (n.b. you need to download and run from your own machine to see the sliders).
It essentially boils down to importing interact, and then passing it a function, along with ranges for the paramters. e.g., from the second link:
In [8]:
def pltsin(f, a):
plot(x,a*sin(2*pi*x*f))
ylim(-10,10)
In [9]:
interact(pltsin, f=(1,10,0.1), a=(1,10,1));
This will produce a plot with two sliders, for f and a.
If you want 3D scatter plot animations, the Ipyvolume Jupyter widget is very impressive.
http://ipyvolume.readthedocs.io/en/latest/animation.html#
bqplot is a really good option to do this now. its built specifically for animation through python in the notebook
https://github.com/bloomberg/bqplot
On #goger's comment of 'horrible flickering', I found that calling clear_output(wait=True) solved my problem. The flag tells clear_output to wait to render till it has something new to render.
matplotlib has an animation module to do just that. However, examples provided on the site will not run as is in a notebook; you need to make a few tweaks to make it work.
Here is the example of the page below modified to work in a notebook (modifications in bold).
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import rc
from IPython.display import HTML
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro', animated=True)
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1, 1)
return ln,
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
return ln,
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
init_func=init, blit=True)
rc('animation', html='html5')
ani
# plt.show() # not needed anymore
Note that the animation in the notebook is made via a movie and that you need to have ffmpeg installed and matplotlib configured to use it.

Resources