0

I want to do something very simple as this example taken from matplotlib Legend documentation but using Bokeh.

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

red_patch = mpatches.Patch(color='red', label='The red data')
plt.legend(handles=[red_patch])

plt.show()

I have data to display similar to the bokeh texas example but when the legend is created, due to the sequence of the polygons in the shapefile it displays the legend correct but with the order of the polygons that it encounters. E.g. if the first polygon is of class 5 the legend displays first the class 5. Since the classes are small number it would be a lot of help if i could manually. Can anyone help?

  • Have you tried what is suggested here: https://stackoverflow.com/questions/25295853/how-to-show-legend-items-of-patches-in-bokeh ? – Zsolt Diveki Mar 14 '18 at 10:41

1 Answers1

0

It would have been better if you had provided the screen shots, and the code. I assume you are talking about the example below

from bokeh.io import show
from bokeh.models import (
    ColumnDataSource,
    HoverTool,
    LogColorMapper
)
from bokeh.palettes import Viridis6 as palette
from bokeh.plotting import figure

from bokeh.sampledata.us_counties import data as counties
from bokeh.sampledata.unemployment import data as unemployment

palette.reverse()

counties = {
    code: county for code, county in counties.items() if county["state"] == "tx"
}

county_xs = [county["lons"] for county in counties.values()]
county_ys = [county["lats"] for county in counties.values()]
county_names = [county['name'] for county in counties.values()]
county_rates = [unemployment[county_id] for county_id in counties]



color_mapper = LogColorMapper(palette=palette)

source = ColumnDataSource(data=dict(
    x=county_xs,
    y=county_ys,
    name=county_names,
    rate=county_rates
))

TOOLS = "pan,wheel_zoom,reset,hover,save"

p = figure(
    title="Texas Unemployment, 2009", tools=TOOLS,
    x_axis_location=None, y_axis_location=None
)
p.grid.grid_line_color = None


p.patches('x', 'y', source=source,
          fill_color={'field': 'rate', 'transform': color_mapper},
          fill_alpha=0.7, line_color="white", line_width=0.5, legend = 'rate')

hover = p.select_one(HoverTool)
hover.point_policy = "follow_mouse"
hover.tooltips = [
    ("Name", "@name"),
    ("Unemployment rate)", "@rate%"),
    ("(Long, Lat)", "($x, $y)"),
]
show(p)

The code can be found at

https://docs.bokeh.org/en/latest/docs/gallery/texas.html

I have just added the legend = 'rate' to add legend.

This will generate a figure as shown here - enter image description here

The legends on the right are in the order of how they have been encountered. This issue has been discusses long back in Bokeh git and this was chosen on purpose.

https://github.com/bokeh/bokeh/issues/1358

That means, you have to change the order in which the rates are encountered (and also change the order of other variables).

You can add following lines of code right after 4 lists county_xs, county_ys, county_names and county_rates are being defined.

t = sorted(zip(county_rates, county_xs, county_ys, county_names))

county_xs = [x for _, x, _, _ in t]
county_ys = [x for _, _, x, _ in t]
county_names = [x for _, _, _, x in t]
county_rates = [x for x, _, _, _ in t]

This is sorting all arrays based on the values of rates. This will give you legends in required format.enter image description here

You can use any custom order, just sort the zipped lists in that order

Hope this helps.

bigreddot
  • 33,642
  • 5
  • 69
  • 122
Aritesh
  • 1,985
  • 1
  • 13
  • 17
  • Thanks for the help! I 've used a similar solution. I created a pandas dataframe from the lists and sort it. But of course this approach is correct and working. Thank you very much again for your effort. – Ignatios Chatzidiamantis Mar 16 '18 at 17:45