How do I set the scatter circle radius in holoviews? - holoviews

Simple question - in bokeh you can plot circles with a radius rather than a size,such that the circles adjust when zooming in or out. Is it possible to do this with a holoviews based scatter - it doesn't have an option currently that I can see for setting the radius and I couldn't work out how to provide it in another manner (eg renders). Likely user error so apologies in advance, many thanks.
import holoviews as hv
hv.extension('bokeh')
from bokeh.plotting import figure, show
x=(1,2,3)
y=(1,2,3)
p=figure()
p.scatter(x, y, radius=0.2)
show(p) # bokeh plot working as expected
scatter=hv.Scatter((x,y)).opts(marker="circle", size=20)
scatter # holoviews plot, cannot code "radius" for code above - causes error.

All hv.Scatter plots are based around Bokeh's Scatter marker which has this section in its docstring:
Note that circles drawn with `Scatter` conform to the standard Marker
interface, and can only vary by size (in screen units) and *not* by radius
(in data units). If you need to control circles by radius in data units,
you should use the Circle glyph directly.
This means that you cannot use hv.Scatter, you have to use something else:
import holoviews as hv
import param
from holoviews.element.chart import Chart
from holoviews.plotting.bokeh import PointPlot
hv.extension('bokeh')
x = (1, 2, 3)
y = (1, 2, 3)
class Circle(Chart):
group = param.String(default='Circle', constant=True)
size = param.Integer()
class CirclePlot(PointPlot):
_plot_methods = dict(single='circle', batched='circle')
style_opts = ['radius' if so == 'size' else so for so in PointPlot.style_opts if so != 'marker']
hv.Store.register({Circle: CirclePlot}, 'bokeh')
scatter = Circle((x, y)).opts(radius=0.5)

Related

obspy plot streams as one plot with different color

Hi I am new to use obspy.
I want to plot two streams to one plot.
I made code as below.
st1=read('/path/1.SAC')
st1+=read('/path/2.SAC')
st1.plot()
I succeed to plot two plots but what I want to do is plotting them as two colors.
When I put the option of 'color', then both colors are changed.
How can I set colors seperately?
Currently it is not possible to change the color of individual waveforms, and changing color will change all waveforms as you mentioned. I suggest you make your own graph from the ObsPy Stream using Matplotlib:
from obspy import read
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
st1=read('/path/1.SAC')
st1+=read('/path/2.SAC')
# Start figure
fig, ax = plt.subplots(nrows=2, sharex='col')
ax[0].plot(st1[0].times("matplotlib"), st1[0].data, color='red')
ax[1].plot(st1[1].times("matplotlib"), st1[1].data, color='blue')
# Format xaxis
xfmt_day = mdates.DateFormatter('%H:%M')
ax[0].xaxis.set_major_formatter(xfmt_day)
ax[0].xaxis.set_major_locator(mdates.MinuteLocator(interval=1))
plt.show()

Log scale for Bokeh bar chart

My code is below. How can I get a log scale for a bokeh hbar plot? Tried x_axis_type="log", but that returned an empty plot.
Edit: I was advised that I must set left to a low but non-zero value in order for it to work, but the new addition left = 0.001 in the code below seem to offset the zero point of the bars on the left, but does not appear as a desired log-scale where the difference between the extreme value in x is visualised as less visually extreme.
Edit (solved): My error in the edit above was that I had not explicitly set the range of the bars. I added x_range=[0.001,1000000] to the code below, and now I get the desired result. See image.
from bokeh.plotting import figure
from bokeh.io import show, output_notebook
output_notebook()
x = [1,5,9,256000]
y = ["a","b","c","d"]
p = figure(y_range=y,x_axis_type = "log",x_range=[0.001,1000000])
p.hbar(y = y, right = x, left = 0.001, height = 0.1)
show(p)
Zero is not a permissible value on a log scale, and as of version 2.3.1 Bokeh does not have anything like Matplotlib's symlog scale that linearizes around the origin. The best you will be able to to is to set left equal to some very small value (but non-zero).

Set the amount of visible bars in the initial plot

I have a barplot using the bokeh library, and I would like to show only the first 5 barplot and then if I want to see the rest of the bars I have to move the x axis to the right or left. I am struggling in find the information that would allow me to do so.
An example would be this:
from bokeh.plotting import figure
from bokeh.io import output_file, show
import calendar
values = [2,3,4,5,6,7,8]
days = [calendar.day_name[i-1] for i in range(1,8)]
p = figure(x_range=days,plot_height=500)
p.vbar(x=days, width=0.5, top=values, color = "#ff1200")
output_file('foo.html')
show(p)
and what I would like it would be something like this:
and then if I want to see the resting of the days I have to click on the figure and move the mouse.
Any idea?
I wasn't able to find a solution for limiting the x axis while using categorical data. Instead I made a workaround where the x axis labels are overridden by days of the week. This makes it possible to use x_range to limit the x axis.
#!/usr/bin/python3
from bokeh.plotting import figure
from bokeh.io import output_file, show
values = [2,3,4,5,6,7,8]
days = [0,1,2,3,4,5,6]
p = figure(x_range=(-0.3,4.3),plot_height=500)
p.xaxis.major_label_overrides = {0:'Monday', 1:'Tuesday', 2:'Wednesday', 3:'Thursday', 4:'Friday', 5:'Saturday', 6:'Sunday'}
p.vbar(x=days, width=0.5, top=values, color = "#ff1200")
output_file('foo.html')
show(p)

ggplot2: aspect_ratio and placing title/axis label in the right place

Using ggplot2 under R (and the code below uses rpy2, I don't actually know straight R, sorry).
I'm trying to add an aspect_ratio to my plot (so it'll fit nicely on a slide). The below example is pretty minimal. Aspect_ratio does the right thing EXCEPT the title and x-axis label are placed way above and below the plot, respectively, with a giant white space between the title and plot and between the plot and x-axis label, as in (plot here):
TITLE TITLE
PLOT PLOT PLOT PLOT
PLOT PLOT PLOT PLOT
PLOT PLOT PLOT PLOT
PLOT PLOT PLOT PLOT
x-axis label
Not cool. What can I do to squeeze them together?
#!/usr/bin/env python2.6
import rpy2.robjects.lib.ggplot2 as ggplot2
import rpy2.robjects as ro
from rpy2.robjects.packages import importr
df = ro.DataFrame({'x': ro.IntVector((1,2)), 'y': ro.IntVector((3,4))})
pp = ggplot2.ggplot(df) + \
ggplot2.aes_string(x='x', y='y') + \
ggplot2.opts(**{'title' : 'Title',
'aspect.ratio' : 0.618033989} ) + \
ggplot2.geom_line()
grdevices = importr('grDevices')
grdevices.pdf(file="aspect.pdf")
pp.plot()
grdevices.dev_off()
This is a limitation in the current layout system, and something I hope to work on soon.

Sharing contour plot attributes between subplots

I'm plotting several contour plots side by side for visualizing the time evolution of certain function. I want each contour's value and color to be shared between all subplots, but each time I add a new subplot, the contour values are recomputed (as shown in the image below), so any comparison between them is meaningless.
Contour plots with colorbars http://www.inf.utfsm.cl/~rbonvall/colorbar-and-contour-plots.png
I've tried setting manually different combinations of cmap, colorbar and axes attributes on each subplot instance, without success. How can I share the contour plot attributes between all the subplots? In other words, how to get the same colorbar for all subplots?
You can directly specify the contour values to be used in the contour plot. Here's an example:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-1.2, 1.2, .025)
y = np.arange(-1.2, 1.2, .025)
X, Y = np.meshgrid(x, y)
Z = np.cos(X)*np.cos(Y)
Z = Z*Z
plt.subplot(1,2,1)
CS = plt.contour(X, Y, Z) # set levels automatically
plt.clabel(CS, inline=1, fontsize=10)
plt.subplot(1,2,2)
CS = plt.contour(X, Y, Z-.1, CS.levels) # set levels as previous levels
plt.clabel(CS, inline=1, fontsize=10)
plt.show()

Resources