Control View in Bokeh State Map - geospatial

I am trying to plot a state with county-level detail using Bokeh and want to be able to control the portion of the state that is visible. I've seen some users suggest deleting counties, but I want to have a rectangular area based on lat/long parameters that controls what portion is shown. Is this possible?

You can control the what is visible on the plot by specifying the x and y ranges. These can be specified either directly in the figure command or by setting the respective attributes using a Range1D. Bokeh will then allow interactive panning respecting while keeping the dimensions of the initial visible area.
If you want to then prevent the user from modifying the visible portion of the plot, you can simply create the figure without any zoom or resize tools.
Here's an example illustrating the above.
from bokeh.plotting import figure, output_file, show
from bokeh.models import Range1d
output_file("title.html")
# Specify tools for the plot
tools = "pan, reset, save"
# create a new plot with a range set with a tuple
p = figure(plot_width=400, plot_height=400,
x_range=(0, 20), tools=tools)
# set a range using a Range1d
p.y_range = Range1d(0, 15)
p.circle([1, 2, 3, 4, 5], [2, 5, 8, 2, 7], size=10)
show(p)

Related

How to change color in pie chart using Matplotlib

I am trying to make v1 as blue, v2 as orange, v3 green and v4 as light grey
I tried going through documentation but cannot understand how to define color in piechart. Thank you for help.
I am using few line of codes of generate a piechart
where vol1 = v1,v2,v3,v4
plt.pie(vol1,labels = vollabels, autopct="%0.2f%%")
plt.legend(title="Normalized Volumes",loc="upper left", fontsize=14)
plt.axis
plt.show()
If you want to have control over which colors your pie chart contains, while at the same time not fall out of matplotlib's convenient handling of colour maps, you might want to have a look at documentation example Nested pie charts. Extracted highlights:
import matplotlib.pyplot as plt
import numpy as np
Retrieve a named colour map and "hand-pick", using a numbered range, suitable colors. The index picking in inner_colors matches hues for a larger numbers of data points in the inner circle:
cmap = plt.get_cmap("tab20c")
outer_colors = cmap(np.arange(3)*4)
inner_colors = cmap(np.array([1, 2, 5, 6, 9, 10]))
The actual plotting, including some customisation, is then straightforward:
fig, ax = plt.subplots()
size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]])
ax.pie(vals.sum(axis=1), radius=1, colors=outer_colors,
wedgeprops=dict(width=size, edgecolor='w'))
ax.pie(vals.flatten(), radius=1-size, colors=inner_colors,
wedgeprops=dict(width=size, edgecolor='w'))
Bonus content in the linked location: how to achieve the same result using a bar plot, but using polar coordinates. That way, one has more flexibility over the exact design, if one's goals diverge from the defaults assumed in pie.

How to control the number of stacked bars through single select widget in python bokeh

I have created a vertical stacked bar chart using python bokeh on an input dataset df using the following code -
print(df.head())
YearMonth A B C D E
0 Jan'18 1587.816 1586.544 856.000 1136.464 1615.360
1 Feb'18 2083.024 1847.808 1036.000 1284.016 2037.872
2 Mar'18 2193.420 1850.524 1180.000 1376.028 2076.464
3 Apr'18 2083.812 1811.636 1192.028 1412.028 2104.588
4 May'18 2379.976 2091.536 1452.000 1464.432 2400.876
Stacked Bar Chart Code -
products = ['python', 'pypy', 'jython']
customers = ['Cust 1', 'Cust 2']
colours = ['red', 'blue']
data = {
'products': products,
'Cust 1': [200, 850, 400],
'Cust 2': [600, 620, 550],
'Retail 1' : [100, 200, 300],
'Retail 2' : [400,500,600]
}
source = ColumnDataSource(data)
# Set up widgets
select=Select(options=['customers','retailers'],value='customers')
def make_plot() :
p=figure()
#p.title.text=select.value
if select.value=='customers' :
customers=['cust 1','cust 2']
else :
customers=['Retail 1','Retail 2']
p.hbar_stack(customers, y='products', height=0.5, source=source, color=colours)
return p
layout = column(select, make_plot())
# Set up callbacks
def update_data(attrname, old, new):
p = make_plot() # make a new plot
layout.children[1] = p
select.on_change('value', update_data)
# # Set up layouts and add to document
curdoc().add_root(layout)
Now I want to limit the number of segments(ie.stacked bars) by using a widget (preferrably by a single select widget). Can anyone please guide me how can i achieve using bokeh serve functionality. I don't want to use Javascript call back function.
This would take some non-trivial work to make happen. The vbar_stack method is a convenience function that actually creates multiple glyph renderers, one for each "row" in the initial stacking. What's more the renderers are all inter-related to one another, via the Stack transform that stacks all the previous renderers at each step. So there is not really any simple way to change the number of rows that are stacked after the fact. So much so that I would suggest simply deleting and re-creating the entire plot in each callback. (I would not normally recommend this approach, but this situation is one of the few exceptions.)
Since you have not given complete code or even mentioned what widget you want to use, all I can provide is a high level sketch of the code. Here is a complete example that updates a plot based on select widget:
from bokeh.layouts import column
from bokeh.models import Select
from bokeh.plotting import curdoc, figure
select = Select(options=["1", "2", "3", "4"], value="1")
def make_plot():
p = figure()
p.circle(x=[0,2], y=[0, 5], size=15)
p.circle(x=1, y=float(select.value), color="red", size=15)
return p
layout = column(select, make_plot())
def update(attr, old, new):
p = make_plot() # make a new plot
layout.children[1] = p # replace the old plot
select.on_change('value', update)
curdoc().add_root(layout)
Note I have changed your show call to curdoc().add_root since it is never useful to call show in a Bokeh server application. You might want to refer to and study the User Guide chapter Running a Bokeh Server for background information, if necessary.

Using RGB values control individual data points matplotlib

I'm trying to be able to control the colour of an individual data point using a corresponding rgb tuple. I've tried looping through the data set and plotting individual data points however I get the same effect as the code I have below; all that happens is it refuses to produce a graph.
This is an example of the data type I'm working with
Any tips?
import matplotlib.pyplot as plt
y=[(0.200,0.1100,0.520)]
for i in range(4):
y.append(y)
plt.plot([1,2,3,4], [3,4,5,2],c=y)
plt.show()
One problem is that you are appending the list to the new list. Instead, try appending the tuple to the list. Moreover, you need to use scatter plot for the color argument which contains rgb tuple for each point. However, in oyur case, I see only a single color for all the scatter points.
tup=(0.200,0.1100,0.520)
y = []
for i in range(4):
y.append(tup)
plt.scatter([1,2,3,4], [3,4,5,2], c=y)
A rather short version to your code is using a list comprehension
tup=(0.200,0.1100,0.520)
y = [tup for _ in range(4)]
plt.scatter([1,2,3,4], [3,4,5,2], c=y)

Bokeh hover doesn't work with the value zero when y_range.start is not provided

Bokeh hover doesn't work with the value zero when y_range.start is not provided, for example, in the case of following code, the hover doesn't display the count '0' when we hover the mouse on Nectarines.
from bokeh.io import show, output_file
from bokeh.models import ColumnDataSource
from bokeh.palettes import Spectral6
from bokeh.plotting import figure
from bokeh.transform import factor_cmap
output_file("colormapped_bars.html")
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
counts = [5, 3, 0, 2, 5, 6]
data = {'fruits' : fruits, 'counts' : counts}
source = ColumnDataSource(data=dict(fruits=fruits, counts=counts))
p = figure(x_range=fruits, plot_height=250, toolbar_location=None, title="Fruit Counts", tools="hover", tooltips="Count: #counts")
p.vbar(x='fruits', top='counts', width=0.9, source=source, legend="fruits", line_color='white', fill_color=factor_cmap('fruits', palette=Spectral6, factors=fruits))
p.xgrid.grid_line_color = None
show(p)
But if I add p.y_range.start = 0, the hover works.
Also hover doesn't work when there is negative range, like p.y_range.start = -5
Please help me what wrong I am doing here.
Thanks In Advance.
I'm not sure what you are expecting. Default "point" hover for a glyph is based on there being a presence on the screen (i.e. actual pixel real estate taken up). Your "Nectarines" bar has zero-height, and therefore takes up no space on the screen. As far as "point" hit-testing for hover goes (the default mode), it is more or less an invisible target. (If it "works" under any circumstances it's almost certainly accidental due to rounding issues.)
If you want the hover to pop up whenever the cursor is anywhere above a bar's category, you can set:
p.hover.mode = "vline"
This is a different hover mode that is able to "see" even zero-height bars

healpy: Formatting subplots

I want to plot many subplots in one figure using healpy. How to:
Set the position of the colorbar?
Set the tick and ticklabel of colorbar?
Set the position and size of the subplots?
I want to generate a plot such as figure 1, which is plotted in MATLAB, based on general coordinates
Right now, I only plot it as follows using healpy:
A similar code to produce figure 3 (similar to figure2) is as follow:
import numpy as np
import healpy as hp
degree = 4
nside = 2**degree
num_Pixel = hp.nside2npix(nside)
m = np.arange(num_Pixel)
margins = [[0.02,0,0,0],[0.01,0,0,0],[0.01,0,0.01,0],
[0.02,0,0,0],[0.01,0,0,0],[0.01,0,0.01,0],
[0.02,0.05,0,0],[0.01,0.05,0,0],[0.01,0.05,0.01,0]]
title = [
'Equinox', 'Jun. Solstice', 'Dec. Solstice',
'','','','','','']
for ifig in range(1,10):
if ifig < 7:
hp.cartview(
m, sub=330+ifig, margins=margins[ifig1],
cbar=False, title=title[ifig-1])
else:
hp.cartview(
m, sub=330+ifig, margins=margins[ifig-1],
cbar=True, title=title[ifig-1])
The code produced the figure 3
I'm afraid healpy doesn't come with a good way to handle the colorbar, ticks, ticklabels, the axes etc.
The best way forward would be to generate FITS images, based on your HEALPix map (e.g. using hp.cartview(..., return_projected_map=True) or using the reproject package).
You also need to generate the right FITS header for that, astropy would be the right tool for that (how-to manipulate FITS headers).
Once you have that, you can use the excellent WCSAxes framework within astropy, which gives you plenty of well-documented customization options.

Resources