2

I need to perform something in bokeh which I am successfully doing in matplotlib.

I plot contour plots using matplotlib along with a colorbar on the side using contourf function. I do not use the meshgrid fuction because I already have X, Y and Z data in (78, 60001) shape arrays each. So this is what works:

array1[0].shape
(78, 60001)
array1[1].shape
(78, 60001)
array1[2].shape
(78, 60001)
CS = plt.contourf(array1[0], array1[1], array1[2], 25, cmap = plt.cm.jet)

Which gives the following results:

3d-fft

How do I do the same thing in bokeh? Most of the examples on the internet and manual are using meshgrid.

===

Update #1: Example: https://docs.bokeh.org/en/latest/docs/gallery/image.html

I tried the above bokeh code as follows:

p.image(array1[2], array1[0], array1[1], dw=10, dh=10, palette="Spectral11")

Which gives the following error:

 RuntimeError: Columns need to be 1D (x is not)

===

Update #2:

p.image(array1[2].ravel(), array1[0].ravel(), array1[1].ravel(), dw=10, dh=None, palette="Spectral11")

Above line of code creates the HTML file but no plot is displayed.

bigreddot
  • 33,642
  • 5
  • 69
  • 122
  • do you mean this example? http://bokeh.pydata.org/en/latest/docs/gallery/image.html I don't think it matters that they're using meshgrid as it appear to pass arrays (like you have) to the plotting function – Paul H Jan 11 '19 at 06:59
  • @PaulH yes I tried exactly the same example. It gives the following error: ```p.image(array1[2], array1[0], array1[1], dw=10, dh=10, palette="Spectral11")``` ```RuntimeError: Columns need to be 1D (x is not)``` – Pushkar Sheth Jan 11 '19 at 07:16
  • in the example, x and y are passed as zero. what happens if you try that? – Paul H Jan 11 '19 at 07:21
  • @PaulH - nope - there is no result. i.e. the html page opens, but there is no plot. Also my dw remains constant, but dh is not constant - it is variable and increasing in ascending order, which is captured in array1[1]. – Pushkar Sheth Jan 11 '19 at 07:26
  • If **nothing** is displayed in the browser, try opening the developer console of the browser (CTRL Shift C in Firefox, then click Console), it often gives an indication of the error – RunOrVeith Jan 11 '19 at 09:22
  • Also check out the second answer (not accepted)[here](https://stackoverflow.com/questions/41282592/how-to-properly-create-a-heatmap-with-bokeh), it shows how to do this with `rect` since `HeatMap` was discontinued – RunOrVeith Jan 11 '19 at 09:25
  • Have a look to the library [hvplot](https://hvplot.holoviz.org/reference/xarray/contourf.html) – lhoupert Jan 07 '21 at 16:14

2 Answers2

1

RuntimeError: Columns need to be 1D (x is not)

The reason for this is that you are attempting to pass coordinates for every pixel of the image, but that is not what Bokeh expects. For each 2D image data (either RGBA array, or scalar data to be color mapped in the client), Bokeh only expects to receive a single value for each of: x, y, dw, and dh. The x and y coordinates are the coordinates of the lower left of the image. The dw and dh are the width and height of the the image in data space coordinates.

It is possible to pass multiple images to a single call to image_rgba or image. In this case x, y, dw, and dh would have a single value for each image. I.e., x would be a 1d array of numbers (one for each image).

bigreddot
  • 33,642
  • 5
  • 69
  • 122
0

I think the hvplot library would answer your question.

See a the reproducible example on an Xarray dataset below:

import xarray as xr
import hvplot.xarray  # noqa

import holoviews as hv
from holoviews import opts
hv.extension('bokeh')

air_ds = xr.tutorial.open_dataset('air_temperature').load()
meanairbyyear = air_ds.air.groupby('time.year').mean()
stdairbyyear = air_ds.air.groupby('time.year').std()

meanair2d = xr.Dataset(
    {
        "y2013": (["lat", "lon"], meanairbyyear[0,:,:]),
        "y2014": (["lat", "lon"], meanairbyyear[1,:,:]),
    },
    coords={
        "lon": ("lon", meanairbyyear.lon),
        "lat": ("lat", meanairbyyear.lat),
    },
)

meanair2d

pl=meanair2d.hvplot.contourf(z='y2013',width=400)

from bokeh.models import HoverTool
MyHover = HoverTool(
    tooltips=[
        ( 'x', '$x'),
        ( 'y', '$y'),
        ( 'Year 2013', '@y2013{%3.0f} degC'),      
   ],
    formatters={
        '$x' : 'numeral',
        '$y' : 'numeral',
        '@y2013' : 'printf',      
    },
    point_policy="follow_mouse"
)

pl.opts(tools = [MyHover])

enter image description here

lhoupert
  • 584
  • 8
  • 25