Exemplo n.º 1
0
 def load_data(path, itime, ipressure):
     print("load_data", path, ipressure, itime)
     step = 100
     with netCDF4.Dataset(path) as dataset:
         var = dataset.variables["x_wind"]
         if len(var.dimensions) == 4:
             values = var[itime, ipressure]
         else:
             values = var[itime]
         u = values[::step, ::step]
         var = dataset.variables["y_wind"]
         if len(var.dimensions) == 4:
             values = var[itime, ipressure]
         else:
             values = var[itime]
         v = values[::step, ::step]
         for d in var.dimensions:
             if "longitude" in d:
                 lons = dataset.variables[d][::step]
             if "latitude" in d:
                 lats = dataset.variables[d][::step]
     gx, _ = geo.web_mercator(lons, np.zeros(len(lons), dtype="d"))
     _, gy = geo.web_mercator(np.zeros(len(lats), dtype="d"), lats)
     x, y = np.meshgrid(gx, gy)
     u = convert_units(u, 'm s-1', 'knots')
     v = convert_units(v, 'm s-1', 'knots')
     return {
         "x": x.flatten(),
         "y": y.flatten(),
         "u": u.flatten(),
         "v": v.flatten()
     }
def web_mercator(lons, lats):
    """Similar to forest.geo.web_mercator but preserves array shape"""
    if (lons.ndim == 1):
        gx, _ = geo.web_mercator(lons, np.zeros(len(lons), dtype="d"))
        _, gy = geo.web_mercator(np.zeros(len(lats), dtype="d"), lats)
        return gx, gy
    elif (lons.ndim == 2) and (lats.ndim == 2):
        gx, gy = geo.web_mercator(lons, lats)
        gx = gx.reshape(lons.shape)
        gx = np.ma.masked_invalid(gx)
        gy = gy.reshape(lats.shape)
        gy = np.ma.masked_invalid(gy)
        return gx, gy
    else:
        raise Exception("Either 1D or 2D lons/lats")
Exemplo n.º 3
0
def xs_ys(lines):
    xs, ys = [], []
    for lons, lats in lines:
        x, y = geo.web_mercator(lons, lats)
        xs.append(x)
        ys.append(y)
    return {"xs": xs, "ys": ys}
Exemplo n.º 4
0
    def load(path):
        print(path)
        with open(path) as stream:
            rdt = json.load(stream)

        copy = dict(rdt)
        for i, feature in enumerate(rdt["features"]):
            coordinates = feature['geometry']['coordinates'][0]
            lons, lats = np.asarray(coordinates).T
            x, y = geo.web_mercator(lons, lats)
            c = np.array([x, y]).T.tolist()
            copy["features"][i]['geometry']['coordinates'][0] = c

        # Hack to use Categorical mapper
        for i, feature in enumerate(rdt["features"]):
            p = feature['properties']['PhaseLife']
            copy["features"][i]['properties']['PhaseLife'] = str(p)

        return json.dumps(copy)
Exemplo n.º 5
0
 def __init__(self, loader):
     frame = loader.frame
     if frame is not None:
         x, y = geo.web_mercator(
                 frame.longitude,
                 frame.latitude)
         date = frame.date
         longitude = frame.longitude
         latitude = frame.latitude
         flash_type = frame.flash_type
     else:
         x, y = [], []
         date = []
         longitude = []
         latitude = []
         flash_type = []
     self.source = bokeh.models.ColumnDataSource({
         "x": x,
         "y": y,
         "date": date,
         "longitude": longitude,
         "latitude": latitude,
         "flash_type": flash_type,
     })
Exemplo n.º 6
0
def main():
    lon_range = (0, 30)
    lat_range = (0, 30)
    x_range, y_range = geo.web_mercator(lon_range, lat_range)
    figure = bokeh.plotting.figure(x_range=x_range,
                                   y_range=y_range,
                                   x_axis_type="mercator",
                                   y_axis_type="mercator",
                                   active_scroll="wheel_zoom")
    tile = bokeh.models.WMTSTileSource(
        url="https://maps.wikimedia.org/osm-intl/{Z}/{X}/{Y}.png",
        attribution="")
    figures = [figure]
    for _ in range(2):
        f = bokeh.plotting.figure(x_range=figure.x_range,
                                  y_range=figure.y_range,
                                  x_axis_type="mercator",
                                  y_axis_type="mercator",
                                  active_scroll="wheel_zoom")
        figures.append(f)

    for f in figures:
        f.axis.visible = False
        f.toolbar.logo = None
        f.toolbar_location = None
        f.min_border = 0
        f.add_tile(tile)

    figure_row = bokeh.layouts.row(*figures, sizing_mode="stretch_both")
    figure_row.children = [figures[0]]  # Trick to keep correct sizing modes

    figure_drop = bokeh.models.Dropdown(label="Figure",
                                        menu=[(str(i), str(i))
                                              for i in [1, 2, 3]])

    def on_click(value):
        if int(value) == 1:
            figure_row.children = [figures[0]]
        elif int(value) == 2:
            figure_row.children = [figures[0], figures[1]]
        elif int(value) == 3:
            figure_row.children = [figures[0], figures[1], figures[2]]

    figure_drop.on_click(on_click)

    color_mapper = bokeh.models.LinearColorMapper(
        low=0, high=1, palette=bokeh.palettes.Plasma[256])
    for figure in figures:
        colorbar = bokeh.models.ColorBar(color_mapper=color_mapper,
                                         orientation="horizontal",
                                         background_fill_alpha=0.,
                                         location="bottom_center",
                                         major_tick_line_color="black",
                                         bar_line_color="black")
        figure.add_layout(colorbar, 'center')

    artist = Artist(figures, color_mapper)
    renderers = []
    for _, r in artist.renderers.items():
        renderers += r

    image_sources = []
    for name, viewer in artist.viewers.items():
        if isinstance(viewer, (view.UMView, view.GPMView)):
            image_sources.append(viewer.source)

    image_loaders = []
    for name, loader in data.LOADERS.items():
        if isinstance(loader, (data.UMLoader, data.GPM)):
            image_loaders.append(loader)

    features = []
    for figure in figures:
        features += [
            add_feature(figure, data.COASTLINES),
            add_feature(figure, data.BORDERS)
        ]
    toggle = bokeh.models.CheckboxButtonGroup(labels=["Coastlines"],
                                              active=[0],
                                              width=135)

    def on_change(attr, old, new):
        if len(new) == 1:
            for feature in features:
                feature.visible = True
        else:
            for feature in features:
                feature.visible = False

    toggle.on_change("active", on_change)

    dropdown = bokeh.models.Dropdown(label="Color",
                                     menu=[("Black", "black"),
                                           ("White", "white")],
                                     width=50)
    dropdown.on_click(change_label(dropdown))

    def on_click(value):
        for feature in features:
            feature.glyph.line_color = value

    dropdown.on_click(on_click)

    slider = bokeh.models.Slider(start=0,
                                 end=1,
                                 step=0.1,
                                 value=1.0,
                                 show_value=False)
    custom_js = bokeh.models.CustomJS(args=dict(renderers=renderers),
                                      code="""
            renderers.forEach(function (r) {
                r.glyph.global_alpha = cb_obj.value
            })
            """)
    slider.js_on_change("value", custom_js)

    palettes = {
        "Viridis": bokeh.palettes.Viridis[256],
        "Magma": bokeh.palettes.Magma[256],
        "Inferno": bokeh.palettes.Inferno[256],
        "Plasma": bokeh.palettes.Plasma[256]
    }
    palette_controls = PaletteControls(color_mapper, palettes)

    mapper_limits = MapperLimits(image_sources, color_mapper)

    menu = [(n, n) for n in data.FILE_DB.names]
    image_controls = images.Controls(menu)

    def on_click(value):
        if int(value) == 1:
            image_controls.labels = ["Show"]
        elif int(value) == 2:
            image_controls.labels = ["L", "R"]
        elif int(value) == 3:
            image_controls.labels = ["L", "C", "R"]

    figure_drop.on_click(on_click)

    variables = image_loaders[0].variables
    pressures = image_loaders[0].pressures
    pressure_variables = image_loaders[0].pressure_variables
    field_controls = FieldControls(variables, pressures, pressure_variables)

    image_controls.subscribe(artist.on_visible)
    field_controls.subscribe(artist.on_field)

    div = bokeh.models.Div(text="", width=10)
    border_row = bokeh.layouts.row(bokeh.layouts.column(toggle),
                                   bokeh.layouts.column(div),
                                   bokeh.layouts.column(dropdown))

    time_controls = TimeControls()
    time_controls.subscribe(field_controls.on_time_control)

    tabs = bokeh.models.Tabs(tabs=[
        bokeh.models.Panel(child=bokeh.layouts.column(
            time_controls.layout, bokeh.layouts.row(field_controls.drop),
            bokeh.layouts.row(field_controls.radio), image_controls.column),
                           title="Data"),
        bokeh.models.Panel(child=bokeh.layouts.column(
            bokeh.layouts.row(figure_drop),
            border_row,
            bokeh.layouts.row(slider),
            bokeh.layouts.row(palette_controls.drop),
            bokeh.layouts.row(mapper_limits.low_input),
            bokeh.layouts.row(mapper_limits.high_input),
            bokeh.layouts.row(mapper_limits.checkbox),
        ),
                           title="Settings")
    ])

    # Series sub-figure widget
    series_figure = bokeh.plotting.figure(plot_width=400,
                                          plot_height=200,
                                          x_axis_type="datetime",
                                          toolbar_location=None,
                                          border_fill_alpha=0)
    series_figure.toolbar.logo = None
    series_row = bokeh.layouts.row(series_figure, name="series")

    def place_marker(figure, source):
        figure.circle(x="x", y="y", color="red", source=source)

        def cb(event):
            source.data = {"x": [event.x], "y": [event.y]}

        return cb

    marker_source = bokeh.models.ColumnDataSource({"x": [], "y": []})

    series = Series(series_figure)
    field_controls.subscribe(series.on_field)
    for f in figures:
        f.on_event(bokeh.events.Tap, series.on_tap)
        f.on_event(bokeh.events.Tap, place_marker(f, marker_source))

    document = bokeh.plotting.curdoc()
    document.add_root(bokeh.layouts.column(tabs, name="controls"))
    document.add_root(series_row)
    document.add_root(figure_row)
Exemplo n.º 7
0
def main():
    args = parse_args.parse_args()
    database = db.Database.connect(args.database)
    with open(args.config_file) as stream:
        config = parse_args.load_config(stream)

    # Access latest files
    data.FILE_DB.sync()

    # Full screen map
    lon_range = (0, 30)
    lat_range = (0, 30)
    x_range, y_range = geo.web_mercator(
        lon_range,
        lat_range)
    figure = bokeh.plotting.figure(
        x_range=x_range,
        y_range=y_range,
        x_axis_type="mercator",
        y_axis_type="mercator",
        active_scroll="wheel_zoom")
    tile = bokeh.models.WMTSTileSource(
        url="https://maps.wikimedia.org/osm-intl/{Z}/{X}/{Y}.png",
        attribution=""
    )

    figures = [figure]
    for _ in range(2):
        f = bokeh.plotting.figure(
            x_range=figure.x_range,
            y_range=figure.y_range,
            x_axis_type="mercator",
            y_axis_type="mercator",
            active_scroll="wheel_zoom")
        figures.append(f)

    for f in figures:
        f.axis.visible = False
        f.toolbar.logo = None
        f.toolbar_location = None
        f.min_border = 0
        f.add_tile(tile)

    figure_row = bokeh.layouts.row(*figures,
            sizing_mode="stretch_both")
    figure_row.children = [figures[0]]  # Trick to keep correct sizing modes

    figure_drop = bokeh.models.Dropdown(
            label="Figure",
            menu=[(str(i), str(i)) for i in [1, 2, 3]])

    def on_change(attr, old, new):
        if int(new) == 1:
            figure_row.children = [
                    figures[0]]
        elif int(new) == 2:
            figure_row.children = [
                    figures[0],
                    figures[1]]
        elif int(new) == 3:
            figure_row.children = [
                    figures[0],
                    figures[1],
                    figures[2]]

    figure_drop.on_change("value", on_change)

    color_mapper = bokeh.models.LinearColorMapper(
            low=0,
            high=1,
            palette=bokeh.palettes.Plasma[256])
    for figure in figures:
        colorbar = bokeh.models.ColorBar(
            color_mapper=color_mapper,
            orientation="horizontal",
            background_fill_alpha=0.,
            location="bottom_center",
            major_tick_line_color="black",
            bar_line_color="black")
        figure.add_layout(colorbar, 'center')

    for name, pattern in config.patterns:
        if name not in data.LOADERS:
            locator = db.Locator(
                database.connection,
                directory=args.directory)
            loader = data.DBLoader(name, pattern, locator)
            data.add_loader(name, loader)

    renderers = {}
    viewers = {}
    for name, loader in data.LOADERS.items():
        if isinstance(loader, rdt.Loader):
            viewer = rdt.View(loader)
        elif isinstance(loader, earth_networks.Loader):
            viewer = earth_networks.View(loader)
        elif isinstance(loader, data.GPM):
            viewer = view.GPMView(loader, color_mapper)
        elif isinstance(loader, satellite.EIDA50):
            viewer = view.EIDA50(loader, color_mapper)
        else:
            viewer = view.UMView(loader, color_mapper)
        viewers[name] = viewer
        renderers[name] = [
                viewer.add_figure(f)
                for f in figures]
    artist = Artist(viewers, renderers)
    renderers = []
    for _, r in artist.renderers.items():
        renderers += r

    image_sources = []
    for name, viewer in artist.viewers.items():
        if isinstance(viewer, (view.UMView, view.GPMView, view.EIDA50)):
            image_sources.append(viewer.source)

    # image_loaders = []
    # for name, loader in data.LOADERS.items():
    #     if isinstance(loader, (data.UMLoader, data.GPM)):
    #         image_loaders.append(loader)

    # Lakes
    for figure in figures:
        add_feature(figure, data.LAKES, color="lightblue")

    features = []
    for figure in figures:
        features += [
            add_feature(figure, data.COASTLINES),
            add_feature(figure, data.BORDERS)]

    # Disputed borders
    for figure in figures:
        add_feature(figure, data.DISPUTED, color="red")

    toggle = bokeh.models.CheckboxButtonGroup(
            labels=["Coastlines"],
            active=[0],
            width=135)

    def on_change(attr, old, new):
        if len(new) == 1:
            for feature in features:
                feature.visible = True
        else:
            for feature in features:
                feature.visible = False

    toggle.on_change("active", on_change)

    dropdown = bokeh.models.Dropdown(
            label="Color",
            menu=[
                ("Black", "black"),
                ("White", "white")],
            width=50)
    autolabel(dropdown)

    def on_change(attr, old, new):
        for feature in features:
            feature.glyph.line_color = new

    dropdown.on_change("value", on_change)

    slider = bokeh.models.Slider(
        start=0,
        end=1,
        step=0.1,
        value=1.0,
        show_value=False)
    custom_js = bokeh.models.CustomJS(
            args=dict(renderers=renderers),
            code="""
            renderers.forEach(function (r) {
                r.glyph.global_alpha = cb_obj.value
            })
            """)
    slider.js_on_change("value", custom_js)

    colors_controls = colors.Controls(
            color_mapper, "Plasma", 256)

    mapper_limits = MapperLimits(image_sources, color_mapper)

    menu = [(n, n) for n in data.FILE_DB.names]
    for k, _ in config.patterns:
        menu.append((k, k))

    image_controls = images.Controls(menu)

    def on_change(attr, old, new):
        if int(new) == 1:
            image_controls.labels = ["Show"]
        elif int(new) == 2:
            image_controls.labels = ["L", "R"]
        elif int(new) == 3:
            image_controls.labels = ["L", "C", "R"]

    figure_drop.on_change("value", on_change)

    image_controls.subscribe(artist.on_visible)

    div = bokeh.models.Div(text="", width=10)
    border_row = bokeh.layouts.row(
        bokeh.layouts.column(toggle),
        bokeh.layouts.column(div),
        bokeh.layouts.column(dropdown))

    # Add prototype database controls
    controls = db.Controls(database, patterns=config.patterns)
    locator = db.Locator(
        database.connection,
        directory=args.directory)
    text = db.View(text="", locator=locator)
    controls.subscribe(text.on_state)
    controls.subscribe(artist.on_state)

    tabs = bokeh.models.Tabs(tabs=[
        bokeh.models.Panel(
            child=bokeh.layouts.column(
                bokeh.models.Div(text="Navigate:"),
                controls.layout,
                bokeh.models.Div(text="Compare:"),
                bokeh.layouts.row(figure_drop),
                image_controls.column,
                text.div),
            title="Control"
        ),
        bokeh.models.Panel(
            child=bokeh.layouts.column(
                border_row,
                bokeh.layouts.row(slider),
                colors_controls.layout,
                bokeh.layouts.row(mapper_limits.low_input),
                bokeh.layouts.row(mapper_limits.high_input),
                bokeh.layouts.row(mapper_limits.checkbox),
                ),
            title="Settings")
        ])

    # Series sub-figure widget
    series_figure = bokeh.plotting.figure(
                plot_width=400,
                plot_height=200,
                x_axis_type="datetime",
                toolbar_location=None,
                border_fill_alpha=0)
    series_figure.toolbar.logo = None
    series_row = bokeh.layouts.row(
            series_figure,
            name="series")

    def place_marker(figure, source):
        figure.circle(
                x="x",
                y="y",
                color="red",
                source=source)
        def cb(event):
            source.data = {
                    "x": [event.x],
                    "y": [event.y]}
        return cb

    marker_source = bokeh.models.ColumnDataSource({
            "x": [],
            "y": []})

    series = Series(series_figure)
    controls.subscribe(series.on_state)
    for f in figures:
        f.on_event(bokeh.events.Tap, series.on_tap)
        f.on_event(bokeh.events.Tap, place_marker(f, marker_source))


    # Minimise controls to ease navigation
    compact_button = bokeh.models.Button(
            label="Compact")
    compact_minus = bokeh.models.Button(label="-", width=50)
    compact_plus = bokeh.models.Button(label="+", width=50)
    compact_navigation = bokeh.layouts.column(
            compact_button,
            bokeh.layouts.row(
                compact_minus,
                compact_plus,
                width=100))
    control_root = bokeh.layouts.column(
            compact_button,
            tabs,
            name="controls")

    display = "large"
    def on_compact():
        nonlocal display
        if display == "large":
            control_root.height = 100
            control_root.width = 120
            compact_button.width = 100
            compact_button.label = "Expand"
            control_root.children = [
                    compact_navigation]
            display = "compact"
        else:
            control_root.height = 500
            control_root.width = 300
            compact_button.width = 300
            compact_button.label = "Compact"
            control_root.children = [compact_button, tabs]
            display = "large"

    compact_button.on_click(on_compact)

    document = bokeh.plotting.curdoc()
    document.title = "FOREST"
    document.add_root(control_root)
    document.add_root(series_row)
    document.add_root(figure_row)