Markers in Holoviews - holoviews

The following script produces a nice scatterplot as in the picture below
from holoviews import extension, dim, opts, Scatter
from pandas import read_csv
extension('bokeh')
url = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv'
df = read_csv(url)
scatterplot = Scatter(df, 'flipper_length_mm', ['body_mass_g','island'] )
scatterplot.opts( color=dim('island').str(), cmap=['red','green','blue'] )
Now, suppose I want to use markers in place of colors for island.
Is there something equivalent to cmap (as in the last line of the script above) for marker?

You can update the code as below to add markers. I have left the colors as is. If you don't need it, can remove that and just keep the markers alone... You can use markers from here
scatterplot.opts( color=dim('island').str(), cmap=['red','green','blue'],
marker=dim('island').categorize({'Torgersen':'circle', 'Biscoe':'diamond', 'Dream':'dash'}) )

Related

How can i update the ColumnDataSource by an "selected.on_change()" event?

First, I created a scatter plot out of geogr. coordinates. If i click on one of these circles a second line-plot next to that scatter plot shows further informations depending on what circle i've clicked. That means i have to update the current ColumnDataSource shown in the line-plot by a new one. But if i click on one of those circles the current Source will not be updated. The line-plot still shows the dataset of the old Source.
I'll try to give you a short example of what i've done so far:
def callback(attr, old, new):
# Depending on what circle i've clicked i start a SQL request
# to gain my dataset i want to plot and the new title of the diagram.
# To change the title actually works:
line_plot.title.text = 'new_title'
# "source_new_values" is a ColumnDataSource created out of a
# SQL-request of my database.
# To change the current source doesn't work. The line-plot is still
# showing the old dataset.
source_current_values = source_new_values
scatter_plot = figure(x_axis_label='lat', y_axis_label='lon')
scatter_plot.circle(x='long', y='lat', source=source_coordinates)
# I use the indices to identify what circle was clicked.
source_coordinates.selected.on_change('indices', callback)
line_plot = figure(x_axis_label='time', x_axis_type='datetime',
y_axis_label='values', title='title')
line_plot.line(x='date', y='value', source=source_current_values)
The solution for tat Problem is I'm not able to update the source by a ColumnDataSource, but by a Dictionary using:
source_current_values.data = Dict("some content")

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.

How to change the extent and position of an existing image in bokeh?

I am displaying 2d data as images of varying shapes in a bokeh server, and therefore need to dynamically update not only the image's data source, but also its dw, dh, x, and y properties. In the dummy example below, these changes are made in a callback function which is connected to a Button widget.
I've figured out that I need to access the glyph attribute of the image's GlyphRenderer object, and I can do so through its update() method (see code). But the changes don't take effect until I click the toolbar's Reset button. I've noticed that the changes also mysteriously take effect the second time I activate the callback() function. What is the proper way to make these changes?
import bokeh.plotting
import bokeh.models
import bokeh.layouts
import numpy as np
# set up the interface
fig1 = bokeh.plotting.figure(x_range=(0, 10), y_range=(0, 10))
im1 = fig1.image([], dw=5, dh=5)
button = bokeh.models.Button(label='scramble')
# add everything to the document
bokeh.plotting.curdoc().add_root(bokeh.layouts.column(button, fig1))
# define a callback and connect it
def callback():
# this always works:
im1.data_source.data = {'image': [np.random.random((100,100))]}
# these changes only take effect after pressing the "Reset"
# button, or after triggering this callback function twice:
im1.glyph.update(x=1, y=1, dw=9, dh=9)
button.on_click(callback)
I don't immediately see why you code isn't work. I can suggest explicitly using a ColumnDataSource and linking all of the Image glyph properties to columns in that source. Then you should be able to update the source.data in a single line and have all of the updates apply.
Here's some incomplete sample code to suggest how to do that:
from bokeh.models import Image, ColumnDataSource
from bokeh.plotting import figure
# the plotting code
plot = figure()
source = ColumnDataSource(data=dict(image=[], x=[], y=[], dw=[], dh=[]))
image = Image(data='image', x='x', y='y', dw='dw', dh=dh)
plot.add_glyph(source, glyph=image)
# the callback
def callback():
source.data = {'image': [np.random.random((100,100))], 'x':[1], 'y':[1], 'dw':[9], 'dh':[9]}
button.on_click(callback)

Importing a Terrain type Google API static map into R without labels

I'm looking to import a Google API static map into R using the GetMap function of the RGoogleMaps package. I then plan to plot data points onto the graph in R using PlotOnStaticMap. I would like to use the "terrain" maptype, but don't want the labels on it. I have found a previous stackoverflow question that addresses how to remove the labels on the map by using "style=feature:all|element:labels|visibility:off".
Map with labels: (http://maps.googleapis.com/maps/api/staticmap?center=29.4,-89.2&zoom=9&size=600x500&maptype=terrain&sensor=false)
Map without labels: (http://maps.googleapis.com/maps/api/staticmap?center=29.4,-89.2&zoom=9&size=600x500&maptype=terrain&sensor=false&style=feature:all|element:labels|visibility:off)
This second code produces the exact map I would like. However, when I save it as a PNG file and then go to import it into R using the GetMaps function, it gives me the original map with all the labels still attached.
Does anyone know how I can get the map without labels imported correctly into R? It seems like it shouldn't be that hard, but I haven't been able to come up with a solution.
Thanks!
Codes in R:
smap<-read.table("D:/sediment/Rfiles/smap.txt", header=TRUE, sep= "");
library(RgoogleMaps)
library(rgdal)
MyMap <- GetMap(center=c(29.4, -89.2), zoom=9,
destfile = "D:/sediment/Rfiles/map.png", maptype="terrain")
map<-PlotOnStaticMap(MyMap, lat=smap$lat, lon=smap$lon,
col=c('black'), add=F,cex=1.1,pch=19)
*smap is a data file of lat, lon coordinates to be plotted on the map
Like this?
MyMap <- GetMap(center=c(29.4, -89.2), zoom=9,
destfile = "D:/sediment/Rfiles/map.png", maptype="terrain",
path = "&style=feature:all|element:labels|visibility:off")

Resources