create side panels in bokeh for displaying details of hovered data point - widget

I have seen great examples of how bokeh allows you to hover over a data point and display pop up details for it. There are cases the details is so overwhelming voluminous, it really requires a side panel to display it all. Is bokeh a complete enough widget toolkit where I can create a side panel to the main display and show details of a data point following the cursor?
Can someone point out some sample code, or at least the relevant api's.

If you prefer a higher-level API for building and linking Bokeh-based plots, you can use HoloViews; see linking examples at http://holoviews.org/reference/index.html#streams and instructions at http://holoviews.org/user_guide/Custom_Interactivity.html . For example:
import param, numpy as np, holoviews as hv
from holoviews import opts, streams
hv.extension('bokeh')
xvals = np.linspace(0,4,202)
ys,xs = np.meshgrid(xvals, -xvals[::-1])
img = hv.Image(np.sin(((ys)**3)*xs))
pointer = streams.PointerXY(x=0,y=0, source=img)
dmap = hv.DynamicMap(lambda x, y: hv.Points([(x, y)]), streams=[pointer])
dmap = dmap.redim.range(x=(-0.5,0.5), y=(-0.5,0.5))
img + dmap.opts(size=10)

You can find many examples on https://docs.bokeh.org . What you want is possible by adding a callback and updating the relevant part. In this example the div is what you name a side panel in your question.
#for bokeh 1.0.4
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource,Div,Row
from bokeh.io import curdoc
from bokeh.events import Tap
#the data
d={'x':[1,2],'y':[3,4],'info':['some information on a first datapoint','some information on a second datapoint']}
source=ColumnDataSource(d)
tooltips = [("x", "$x"),("y", "$y"),("info","#info")]
fig=figure(tools="tap,reset",tooltips=tooltips)
c=fig.circle('x','y',source=source,size=15)
def callback(event):
indexActive=source.selected.indices[0]
layout.children[1]=Div(text=d['info'][indexActive])#adjust the info on the right
fig.on_event(Tap, callback)
div=Div(text=d['info'][0])
layout=Row(fig,div)
curdoc().add_root(layout)
To run this code, save it as code.py, open a cmd and type "bokeh serve code.py --show".

Related

How to load more element from web pages using BeautifulSoup and/or selenium

I would like to get each link that the each boxes contain, the page is https://www.quattroruote.it/listino/audi
In this webpage there are all the model that this brand is producing, and each model is a boxes that links to another page (the one in which I should work with).
My problem is that the initial page do not load all the boxes the first time, you have to scroll down and press the red button "Carica altri modelli" (which mean "Load other models").
Is there a way to automatically store in one variable all the links that i need? For example, the first links of the first box is "/listino/audi/a1"
Thanks in advance to anyone who try to help me!!
Not sure exactly what links you want, but you can make the requests iterating through the itemStart parameter.
import requests
from bs4 import BeautifulSoup
for i in range(1,100):
print('\t\tList start %s' %i)
url = 'https://www.quattroruote.it/listino/ricerca-more-desktop.html'
payload = {
'area': 'NEW',
'itemStart': '%s' %(i*8),
'_': '1634219611449'}
response = requests.get(url, params=payload)
soup = BeautifulSoup(response.text, 'html.parser')
links = soup.find_all('a', href=True)
for link in links:
print(link['href'])

Get links from summary section of wikipedia page

I am trying to extract links from the summary section of a wikipedia page. I tried the below methods :
This url extracts all the links of the Deep learning page:
https://en.wikipedia.org/w/api.php?action=query&prop=links&titles=Deep%20learning
And for extracting links associated to any section I can filter based on the section id - for e.g.,
for the Definition section of same page I can use this url : https://en.wikipedia.org/w/api.php?action=parse&prop=links&page=Deep%20learning&section=1
for the Overview section of same page I can use this url : https://en.wikipedia.org/w/api.php?action=parse&prop=links&page=Deep%20learning&section=2
But I am unable to figure out how to extract only the links from summary section
I even tried using pywikibot to extract linkedpages and adjusting plnamespace variable but couldn't get links only for summary section.
You need to use https://en.wikipedia.org/w/api.php?action=parse&prop=links&page=Deep%20learning&section=0
Note that this also includes links in the
{{machine learning bar}} and {{Artificial intelligence|Approaches}} templates however (to the right of the screen).
You can use Pywikibot with the following commands
>>> import pywikibot
>>> from pwikibot import textlib
>>> site = pywikibot.Site('wikipedia:en') # create a Site object
>>> page = pywikibot.Page(site, 'Deep learning') # create a Page object
>>> sect = textlib.extract_sections(page.text, site) # divide content into sections
>>> links = sorted(link.group('title') for link in pywikibot.link_regex.finditer(sect.head))
Now links is a list containing all link titles in alphabethical order. If you prefer Page objects as result you may create them with
>>> pages = [pywikibot.Page(site, title) for title in links]
It's up to you to create a script with this code snippets.

Unable to display tabs of DataTable inline in Jupyter notebook

I am trying to display multiple dataframe in tabs using Bokeh. My code works when I save my file as html, but it fail to display inline in the Jupyter notebook.
Here is my code:
from bokeh.models.widgets import DataTable, DateFormatter,
TableColumn, Panel, Tabs
from bokeh.io import output_notebook, show
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.resources import INLINE
output_notebook(resources=INLINE)
source = ColumnDataSource(train.head())
columns = [TableColumn(field=col, title=col) for col in train.columns.tolist()]
data_table = DataTable(source=source, columns=columns, width=400, height=280)
tab1 = Panel(child=data_table, title="Train")
source = ColumnDataSource(prop.head())
columns = [TableColumn(field=col, title=col) for col in prop.columns.tolist()]
data_table = DataTable(source=source, columns=columns, width=len(columns)*100, height=280)
tab2 = Panel(child=data_table, title="Properties")
tabs = Tabs(tabs=[tab1, tab2])
show(tabs)
Here is the error messege:
Javascript error adding output!
Error: SlickGrid's 'enableColumnReorder = true' option requires jquery-ui.sortable module to be loaded
See your browser Javascript console for more details.
Here is my set up:
Python 3.6.1 :: Anaconda custom (64-bit)
Ubuntu 16.04 LTS
jupyter==1.0.0
jupyter-client==5.0.1
jupyter-console==5.1.0
jupyter-core==4.3.0
bokeh==0.12.7
Can someone point me a direction as what I can do to fix this?
Thanks in advance!
Mike
That looks like a SlickGrid error message. Like it says, jQueryUI.sortable is a dependency for SlickGrid.
I normally include the full build of jQueryUI in the page, along with jQuery itself, like:
<script src="../lib/jquery-1.11.2.min.js"></script>
<script src="../lib/jquery-ui-1.11.3.min.js"></script>
(or you could use the jQuery CDN).
You can also include a cut down version of jQueryUI that just includes sortable (there are known conflicts between jQueryUI and other frameworks, for example Bootstrap).
If slickgrid is part of the page, you should already have this stuff set up though.
I have no clue about Bokeh.

Replace picture (from page header)

I have a base .docx for which I need to change the page header / footer image on a case by case basis. I read that python-docx does not yet handle headers/footers but it does handle Pictures.
What I cannot work around is how to replace them.
I found the Pictures in the documents ._package.parts objects as ImagePart, I could even try to identify the image by its partname attribute.
What I could not find in any way is how to replace the image. I tried replacing the ImagePart ._blob and ._image attributes but it makes no difference after saving.
So, what would be the "good" way to replace one Image blob with another one using python-docx? (it is the only change I need to do).
Current code is:
d = Document(docx='basefile.docx')
parts = d._package
for p in parts:
if isinstance(p, docx.parts.image.ImagePart) and p.partname.find('image1.png'):
img = p
break
img._blob = open('newfile.png', 'r').read()
d.save('newfile.docx')
Thanks,
marc
There is no requirement to use python-docx. I found another Python library for messing with docx files called "paradocx" altought it seems a bit abandoned it works for what I need.
python-docx would be preferable as the project seems more healthy so a solution based on it is still desired.
Anyway, here is the paradocx based solution:
from paradocx import Document
from paradocx.headerfooter import HeaderPart
template = 'template.docx'
newimg = open('new_file.png', 'r')
doc = Document.from_file(template)
header = doc.get_parts_by_class(HeaderPart).next()
img = header.related('http://schemas.openxmlformats.org/officeDocument/2006/relationships/image')[0]
img.data = newimg.read()
newimg.close()
doc.save('prueba.docx')

How do you import an xkcd fig to html using mpld3

I am trying to import a matplotlib to html with xkcd theme. My code is as follows (no data,just a fig)
fig = plt.figure(facecolor = '#eee8d5')
#plt.matplotlib.rcdefaults()
with plt.xkcd():
ax = fig.add_subplot(111)
ax.set_axis_bgcolor('#eee8d5') #set_color('#fdf6e3')
ax.title.set_color('#d33682') # Magenta
ax.tick_params(axis='x', colors='#657b83')
ax.tick_params(axis='y', colors='#657b83')
ax.spines['bottom'].set_color('#657b83')
ax.spines['left'].set_color('#657b83')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.set_title('Title', fontsize = 18);
html = mpld3.fig_to_html(fig)
Html_file= open("CumPrctWordFrq.html","w")
Html_file.write(html)
Html_file.close()
So far so good -- everything renders correctly in the python notebook. However when I paste the html on a website (squarespace), the fig loses all the xkcd properties. Eventually I would like to make this interactive. The idea is eventually to produce a xkcd -> solarized -> interactive plot.
mpld3 does not yet support the plt.xkcd() mode. If this is something you want, you should creat an issue in the mpld3 issue tracker, and see if someone is inspired to work on it.