Ejemplo n.º 1
0
class BokehPlot(metaclass=ABCMeta):
    """Base class for bokeh plots"""
    def __init__(
        self,
        use_notebook=None,
        autoscale=True,
        cmap="inferno",
        norm="lin",
        **figure_kwargs,
    ):
        # only use autoshow / use_notebook by default if we are in a notebook
        self._use_notebook = use_notebook if use_notebook is not None else is_notebook(
        )
        self._patches = None
        self._handle = None
        self._color_bar = None
        self._color_mapper = None
        self._palette = None
        self._annotations = []
        self._labels = []

        self.cmap = cmap
        self.norm = norm

        self.autoscale = autoscale

        self.datasource = ColumnDataSource(data={})
        self.figure = figure(**figure_kwargs)
        self.figure.add_tools(
            HoverTool(tooltips=[("id", "@id"), ("value", "@values")]))

        if figure_kwargs.get("match_aspect"):
            # Make sure the box zoom tool does not distort the camera display
            for tool in self.figure.toolbar.tools:
                if isinstance(tool, BoxZoomTool):
                    tool.match_aspect = True

    def show(self):
        """Display the figure"""
        if self._use_notebook:
            output_notebook()
        else:
            # this only sets the default name, created only when show is called
            output_file(
                tempfile.mktemp(prefix="ctapipe_bokeh_", suffix=".html"))

        self._handle = show(self.figure, notebook_handle=self._use_notebook)

    def update(self):
        """Update the figure"""
        if self._use_notebook and self._handle:
            push_notebook(handle=self._handle)

    def add_colorbar(self):
        self._color_bar = ColorBar(
            color_mapper=self._color_mapper,
            label_standoff=12,
            border_line_color=None,
            location=(0, 0),
        )
        self.figure.add_layout(self._color_bar, "right")
        self.update()

    def set_limits_minmax(self, zmin, zmax):
        """Set the limits of the color range to ``zmin`` / ``zmax``"""
        self._color_mapper.update(low=zmin, high=zmax)
        self.update()

    def set_limits_percent(self, percent=95):
        """Set the limits to min / fraction of max value"""
        low = np.nanmin(self.datasource.data["values"])
        high = np.nanmax(self.datasource.data["values"])

        frac = percent / 100.0
        self.set_limits_minmax(low, high - (1.0 - frac) * (high - low))

    @property
    def cmap(self):
        """Get the current colormap"""
        return self._palette

    @cmap.setter
    def cmap(self, cmap):
        """Set colormap"""
        if isinstance(cmap, str):
            cmap = palette_from_mpl_name(cmap)

        self._palette = cmap
        # might be called in __init__ before color mapper is setup
        if self._color_mapper is not None:
            self._color_mapper.palette = cmap
            self._trigger_cm_update()
            self.update()

    def _trigger_cm_update(self):
        # it seems changing palette does not trigger a color change,
        # so we reassign a property
        if isinstance(self._color_mapper, CategoricalColorMapper):
            self._color_mapper.update(factors=self._color_mapper.factors)
        else:
            self._color_mapper.update(low=self._color_mapper.low)

    def clear_overlays(self):
        """Remove any added overlays from the figure"""
        while self._annotations:
            self.figure.renderers.remove(self._annotations.pop())

        while self._labels:
            self.figure.center.remove(self._labels.pop())

    def rescale(self):
        """Scale pixel colors to min/max range"""
        low = self.datasource.data["values"].min()
        high = self.datasource.data["values"].max()

        # force color to be at lower end of the colormap if
        # data is all equal
        if low == high:
            high += 1

        self.set_limits_minmax(low, high)

    @property
    def norm(self):
        """
        The norm instance of the Display

        Possible values:

        - "lin": linear scale
        - "log": log scale (cannot have negative values)
        - "symlog": symmetric log scale (negative values are ok)
        """
        return self._color_mapper

    @norm.setter
    def norm(self, norm):
        """Set the norm"""
        if not isinstance(norm, ContinuousColorMapper):
            if norm == "lin":
                norm = LinearColorMapper
            elif norm == "log":
                norm = LogColorMapper
            else:
                raise ValueError(f"Unsupported norm {norm}")

        self._color_mapper = norm(self.cmap)
        if self._patches is not None:
            color = dict(transform=self._color_mapper)
            self._patches.glyph.update(fill_color=color, line_color=color)

        if self._color_bar is not None:
            self._color_bar.update(color_mapper=self._color_mapper)

        self.update()
p = figure(width=800,
           height=300,
           title="US unemployment 1948—2016",
           x_range=list(data.index),
           y_range=list(reversed(data.columns)),
           toolbar_location=None,
           tools="",
           x_axis_location="above")

p.rect(x="Year",
       y="Month",
       width=1,
       height=1,
       source=source,
       line_color=None,
       fill_color=transform('rate', mapper))

color_bar = ColorBar(color_mapper=mapper,
                     ticker=BasicTicker(desired_num_ticks=len(colors)),
                     formatter=PrintfTickFormatter(format="%d%%"))

p.add_layout(color_bar, 'right')

p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = "7px"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = 1.0

show(p)
def get_figure(year: int):
    '''
    @Author: Haoyang Ding
    create bokeh figure object
    :param year: year
    :return: figure
    '''
    df_year = df[df['year'] == year]
    # Merge dataframes gdf and df_2016.
    merged = gdf.merge(df_year, left_on='country_code', right_on='code')

    # Read data to json.
    merged_json = json.loads(merged.to_json())
    # Convert to String like object.
    json_data = json.dumps(merged_json)

    # Input GeoJSON source that contains features for plotting.
    geosource = GeoJSONDataSource(geojson=json_data)
    # Define a sequential multi-hue color palette.
    palette = brewer['RdBu'][11]
    # Reverse color order so that dark blue is highest obesity.
    # Instantiate LinearColorMapper that linearly maps numbers in a range, into a sequence of colors.
    color_mapper = LinearColorMapper(palette=palette, low=-2, high=2)
    # Define custom tick labels for color bar.
    tick_labels = {
        '0': '0°C',
        '-0.5': '-0.5°C',
        '-1': '-1°C',
        '-1.5': '-1.5°C',
        '-2': '-2°C',
        '0.5': '0.5°C',
        '1': '1°C',
        '1.5': '1.5°C',
        '2': '2°C'
    }
    # Create color bar.
    color_bar = ColorBar(color_mapper=color_mapper,
                         label_standoff=8,
                         width=500,
                         height=20,
                         border_line_color=None,
                         location=(0, 0),
                         orientation='horizontal',
                         major_label_overrides=tick_labels)
    # Create figure object.
    p = figure(title='Surface temperature anomaly (degrees celcius), ' +
               str(year),
               plot_height=600,
               plot_width=950,
               toolbar_location=None)
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None
    # Add patch renderer to figure.
    p.patches('xs',
              'ys',
              source=geosource,
              fill_color={
                  'field': 'temperature',
                  'transform': color_mapper
              },
              line_color='black',
              line_width=0.25,
              fill_alpha=1)
    # Specify figure layout.
    p.add_layout(color_bar, 'below')
    return p
source = ColumnDataSource(dict(x=x, y=y, z=z))

p = figure(plot_width=600,
           plot_height=600,
           title="Sum of bill values / week day 0=Monday, 6=Sunday")

p.circle(x='x',
         y='y',
         line_color=mapper,
         color=mapper,
         fill_alpha=1,
         size=10,
         source=source)

color_bar = ColorBar(color_mapper=mapper['transform'],
                     width=8,
                     location=(0, 0))

p.add_layout(color_bar, 'right')

show(p)

output_file("bills per hour.html", title="Sum of bill values per hour")

x = grouped_filtered_value_and_time.loc[:, 'T']
y = grouped_filtered_value_and_time.loc[:, 'RFV']
z = grouped_filtered_value_and_time.loc[:, 'S']

#Use the field name of the column source
mapper = linear_cmap(field_name='z',
                     palette=Spectral6,
Ejemplo n.º 5
0
def heatmap_viz(
    df: pd.DataFrame,
    x: str,
    y: str,
    grp_cnt_stats: Dict[str, int],
    plot_width: int,
    plot_height: int,
    max_lbl_len: int = 15,
) -> Panel:
    """
    Render a heatmap
    """
    # pylint: disable=too-many-arguments
    title = _make_title(grp_cnt_stats, x, y)

    source = ColumnDataSource(data=df)
    palette = BIPALETTE[(len(BIPALETTE) // 2 - 1):]
    mapper = LinearColorMapper(palette=palette,
                               low=df["cnt"].min() - 0.01,
                               high=df["cnt"].max())
    if grp_cnt_stats["x_show"] > 60:
        plot_width = 16 * grp_cnt_stats["x_show"]
    if grp_cnt_stats["y_show"] > 10:
        plot_height = 70 + 18 * grp_cnt_stats["y_show"]
    fig = figure(
        x_range=list(set(df["x"])),
        y_range=list(set(df["y"])),
        toolbar_location=None,
        tools=[],
        x_axis_location="below",
        title=title,
        plot_width=plot_width,
        plot_height=plot_height,
    )

    renderer = fig.rect(
        x="x",
        y="y",
        width=1,
        height=1,
        source=source,
        line_color=None,
        fill_color=transform("cnt", mapper),
    )

    color_bar = ColorBar(
        color_mapper=mapper,
        location=(0, 0),
        ticker=BasicTicker(desired_num_ticks=7),
        formatter=PrintfTickFormatter(format="%d"),
    )
    fig.add_tools(
        HoverTool(
            tooltips=[
                (x, "@x"),
                (y, "@y"),
                ("Count", "@cnt"),
            ],
            mode="mouse",
            renderers=[renderer],
        ))
    fig.add_layout(color_bar, "right")

    tweak_figure(fig, "heatmap")
    fig.yaxis.formatter = FuncTickFormatter(code="""
        if (tick.length > %d) return tick.substring(0, %d-2) + '...';
        else return tick;
    """ % (max_lbl_len, max_lbl_len))
    return Panel(child=fig, title="heat map")
Ejemplo n.º 6
0
p.axis.major_label_text_font_size = "5pt"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = pi / 3

p.rect(x='B1',
       y='B2',
       width=1,
       height=1,
       source=source,
       fill_color={
           'field': 'corr',
           'transform': mapper
       },
       line_color=None)

color_bar = ColorBar(color_mapper=mapper,
                     major_label_text_font_size="5pt",
                     ticker=BasicTicker(desired_num_ticks=len(colors)),
                     formatter=PrintfTickFormatter(format="%f"),
                     label_standoff=6,
                     border_line_color=None,
                     location=(0, 0))
p.add_layout(color_bar, 'right')

p.select_one(HoverTool).tooltips = [
    ('B1', '@B1'),
    ('B2', '@B2'),
    ('corr', '@corr'),
]

show(p)
Ejemplo n.º 7
0
p.axis.major_label_text_font_size = "5pt"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = np.pi / 3

p.rect('xname',
       'yname',
       0.9,
       0.9,
       source=data,
       line_color=None,
       hover_line_color='black',
       alpha='alphas')

mapper = LinearColorMapper(palette=Magma6, low=0, high=1)
color_bar = ColorBar(color_mapper=mapper,
                     border_line_color=None,
                     location=(0, 0))

data1 = dict(
    xname=xname,
    yname=yname,
    count=counts,
)

plot = figure(title="Matrix Author Similarity",
              x_axis_location="above",
              x_range=list(reversed(names1)),
              y_range=names1,
              toolbar_location='below')
hover = HoverTool(tooltips=[('Names', '@yname, @xname'), ('Value', '@count')])
plot.add_tools(hover)
Ejemplo n.º 8
0
Archivo: ui.py Proyecto: the-sea/ray
def cluster_usage():
    from bokeh.io import show, output_notebook, push_notebook
    from bokeh.resources import CDN
    from bokeh.plotting import figure
    from bokeh.models import (
        ColumnDataSource,
        HoverTool,
        LinearColorMapper,
        BasicTicker,
        ColorBar,
    )
    output_notebook(resources=CDN)

    # Initial values
    source = ColumnDataSource(
        data={
            "node_ip_address": ['127.0.0.1'],
            "time": ['0.5'],
            "num_tasks": ['1'],
            "length": [1]
        })

    # Define the color schema
    colors = [
        "#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1",
        "#cc7878", "#933b41", "#550b1d"
    ]
    mapper = LinearColorMapper(palette=colors, low=0, high=2)

    TOOLS = "hover, save, xpan, box_zoom, reset, xwheel_zoom"

    # Create the plot
    p = figure(title="Cluster Usage",
               y_range=list(set(source.data['node_ip_address'])),
               x_axis_location="above",
               plot_width=900,
               plot_height=500,
               tools=TOOLS,
               toolbar_location='below')

    # Format the plot axes
    p.grid.grid_line_color = None
    p.axis.axis_line_color = None
    p.axis.major_tick_line_color = None
    p.axis.major_label_text_font_size = "10pt"
    p.axis.major_label_standoff = 0
    p.xaxis.major_label_orientation = np.pi / 3

    # Plot rectangles
    p.rect(x="time",
           y="node_ip_address",
           width="length",
           height=1,
           source=source,
           fill_color={
               "field": "num_tasks",
               "transform": mapper
           },
           line_color=None)

    # Add legend to the side of the plot
    color_bar = ColorBar(color_mapper=mapper,
                         major_label_text_font_size="8pt",
                         ticker=BasicTicker(desired_num_ticks=len(colors)),
                         label_standoff=6,
                         border_line_color=None,
                         location=(0, 0))
    p.add_layout(color_bar, "right")

    # Define hover tool
    p.select_one(HoverTool).tooltips = [
        ("Node IP Address", "@node_ip_address"),
        ("Number of tasks running", "@num_tasks"), ("Time", "@time")
    ]

    # Define the axis labels
    p.xaxis.axis_label = "Time in seconds"
    p.yaxis.axis_label = "Node IP Address"
    handle = show(p, notebook_handle=True)
    workers = ray.global_state.workers()

    # Function to update the heat map
    def heat_map_update(abs_earliest, abs_latest, abs_num_tasks, tasks):
        if len(tasks) == 0:
            return

        earliest = time.time()
        latest = 0

        node_to_tasks = dict()
        # Determine which task has the earlest start time out of the ones
        # passed into the update function
        for task_id, data in tasks.items():
            if data["score"] > latest:
                latest = data["score"]
            if data["score"] < earliest:
                earliest = data["score"]
            worker_id = data["worker_id"]
            node_ip = workers[worker_id]["node_ip_address"]
            if node_ip not in node_to_tasks:
                node_to_tasks[node_ip] = {}
            node_to_tasks[node_ip][task_id] = data

        nodes = []
        times = []
        lengths = []
        num_tasks = []

        for node_ip, task_dict in node_to_tasks.items():
            left, right, top = compute_utilizations(earliest, latest,
                                                    abs_num_tasks, task_dict,
                                                    100, True)
            for (l, r, t) in zip(left, right, top):
                nodes.append(node_ip)
                times.append((l + r) / 2)
                lengths.append(r - l)
                num_tasks.append(t)

        # Set the y range of the plot to be the node IP addresses
        p.y_range.factors = list(set(nodes))

        mapper.low = min(min(num_tasks), 0)
        mapper.high = max(max(num_tasks), 1)

        # Update plot with new data based on slider and text box values
        source.data = {
            "node_ip_address": nodes,
            "time": times,
            "num_tasks": num_tasks,
            "length": lengths
        }

        push_notebook(handle=handle)

    get_sliders(heat_map_update)
Ejemplo n.º 9
0

def normal2d(X, Y, sigx=1.0, sigy=1.0, mux=0.0, muy=0.0):
    z = (X - mux)**2 / sigx**2 + (Y - muy)**2 / sigy**2
    return np.exp(-z / 2) / (2 * np.pi * sigx * sigy)


X, Y = np.mgrid[-3:3:100j, -2:2:100j]
Z = normal2d(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1 * normal2d(X, Y, 1.0, 1.0)
image = Z * 1e6

color_mapper = LogColorMapper(palette="Viridis256", low=1, high=1e7)

plot = figure(x_range=(0, 1), y_range=(0, 1), toolbar_location=None)
plot.image(image=[image],
           color_mapper=color_mapper,
           dh=[1.0],
           dw=[1.0],
           x=[0],
           y=[0])

color_bar = ColorBar(color_mapper=color_mapper,
                     ticker=LogTicker(),
                     label_standoff=12,
                     border_line_color=None,
                     location=(0, 0))

plot.add_layout(color_bar, 'right')

show(plot)
Ejemplo n.º 10
0
path = Label(x=-76.3,
             y=31.4,
             angle=-36.5,
             angle_units="deg",
             text="Solar eclipse path of totality",
             text_baseline="middle",
             text_font_size="8pt",
             text_color="silver")
p.add_layout(path)

color_bar = ColorBar(color_mapper=mapper,
                     location="bottom_left",
                     orientation="horizontal",
                     title="Popularity of \"solar eclipse\" search term",
                     title_text_font_size="12pt",
                     title_text_font_style="bold",
                     title_text_color="lightgrey",
                     major_label_text_color="lightgrey",
                     background_fill_alpha=0.0)
p.add_layout(color_bar)

notes = Label(
    x=0,
    y=0,
    x_units="screen",
    y_units="screen",
    x_offset=40,
    y_offset=20,
    text="Source: Google Trends, NASA Scientific Visualization Studio",
    level="overlay",
Ejemplo n.º 11
0
def NLD_processing(df):
    # get original column names from df
    list_columns_names = df.columns

    # change the column labels from strings to integers
    list_columns_int = []

    for number in range(0, len(df.index.values)):
        list_columns_int.append(number)

    df.columns = list_columns_int

    # change the rows labels/ indexes from strings to integers
    df['index'] = list_columns_int
    df.set_index("index", inplace=True)

    # Making a function to map color to edges
    color_palette = list(reversed(Viridis11[:8]))
    w_max = df.values.max()
    w_min = df.values.min()
    step = (w_max - w_min) / (len(color_palette) - 1)

    colors = []
    # Create a graph with 1-way edges for faster painting
    g = nx.DiGraph()
    for row in df.index.values:
        g.add_node(row)
        for column in df.index.values:
            if row < column:
                if (df[row][column] > 0):
                    color_index = int((df[row][column] - w_min) / step)
                    g.add_edge(row,
                               column,
                               weight=df[row][column],
                               color=color_palette[color_index])
                    colors.append(color_palette[color_index])

    weights = []
    # Create a separate graph with 2-way edges only to calculate weights
    g_w = nx.DiGraph()
    for row in df.index.values:
        g_w.add_node(row)
        for column in df.index.values:
            if row != column:
                if (df[row][column] > 0):
                    g_w.add_edge(row,
                                 column,
                                 weight=df[row][column],
                                 color=color_palette[color_index])
                    weights.append(df[row][column])

    # do not draw edges with different widths if the max weight is too big
    if max(weights) > 30:
        for index, w in enumerate(weights):
            weights[index] = 1

    # loop over all nodes to find neighbors and set min, max, sum for egdes weights connected to a node
    node_w_dict = {}
    for n in list_columns_int:
        node_weight_list = []
        for nb in nx.neighbors(g_w, n):
            node_weight_list.append(
                nx.get_edge_attributes(g_w, 'weight')[n, nb])
        len_list = len(node_weight_list)
        if len_list != 0:
            node_min_weight = min(node_weight_list)
            node_max_weight = max(node_weight_list)
            node_sum_weight = sum(node_weight_list)
            node_avr_weight = node_sum_weight / len_list
        else:
            node_min_weight = 0
            node_max_weight = 0
            node_sum_weight = 0
            node_avr_weight = 0
        node_w_dict.update({
            n: {
                'minweight': node_min_weight,
                'maxweight': node_max_weight,
                'avrweight': node_avr_weight,
                'sumweight': node_sum_weight
            }
        })
    nx.set_node_attributes(g, node_w_dict)

    # Making a function to map node size
    deg_node_size_list = [
        5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
        24, 25, 26, 27, 28, 29, 30
    ]
    deg_max = max(list(list(zip(*g.degree))[1]))
    deg_min = min(list(list(zip(*g.degree))[1]))
    deg_step = (deg_max - deg_min) / (len(deg_node_size_list) - 1)
    i = 0
    node_s_dict = {}
    for node in list(list(zip(*g.degree))[0]):
        deg_index = int(
            (list(list(zip(*g.degree))[1])[i] - deg_min) / deg_step)
        node_s_dict.update({node: {'nodesize': deg_node_size_list[deg_index]}})
        i += 1
    nx.set_node_attributes(g, node_s_dict)

    # create a dictoinary with double for loop
    mapping = {
        old_label: new_label
        for old_label, new_label in itertools.zip_longest(
            sorted(g.nodes()), list_columns_names, fillvalue=1)
    }

    # relabel the names of the nodes from integers back to strings
    nx.relabel_nodes(g, mapping, copy=False)

    # Organize common layouts' size for NLD
    NLD_width = 780
    NLD_height = 690

    color_mapper = LinearColorMapper(palette=color_palette,
                                     low=w_min,
                                     high=w_max)
    color_bar = ColorBar(color_mapper=color_mapper,
                         border_line_color=None,
                         location=(0, 0))

    # circular layout
    plot_circle = Plot(plot_width=NLD_width,
                       plot_height=NLD_height,
                       x_range=Range1d(-1.1, 1.1),
                       y_range=Range1d(-1.1, 1.1))

    graph_circle = NLD_pocessing_graph(g, weights, colors, nx.circular_layout)

    NLD_add_tools(plot_circle)

    plot_circle.add_layout(color_bar, 'right')

    plot_circle.renderers.append(graph_circle)

    # spring layout
    plot_spring = Plot(plot_width=NLD_width,
                       plot_height=NLD_height,
                       x_range=Range1d(-1.1, 1.1),
                       y_range=Range1d(-1.1, 1.1))

    graph_spring = NLD_pocessing_graph(g, weights, colors, nx.spring_layout)

    NLD_add_tools(plot_spring)

    plot_spring.add_layout(color_bar, 'right')

    plot_spring.renderers.append(graph_spring)

    # force-directed layout
    plot_fd = Plot(plot_width=NLD_width,
                   plot_height=NLD_height,
                   x_range=Range1d(-1.1, 1.1),
                   y_range=Range1d(-1.1, 1.1))

    graph_fd = NLD_FD_pocessing_graph(g, weights, colors)

    NLD_add_tools(plot_fd)

    plot_fd.add_layout(color_bar, 'right')

    plot_fd.renderers.append(graph_fd)

    # random layout
    plot_random = Plot(plot_width=NLD_width,
                       plot_height=NLD_height,
                       x_range=Range1d(-0.1, 1.1),
                       y_range=Range1d(-0.1, 1.1))

    graph_random = NLD_random_processing_graph(g, weights, colors,
                                               nx.random_layout)

    NLD_add_tools(plot_random)

    plot_random.add_layout(color_bar, 'right')

    plot_random.renderers.append(graph_random)

    # Create panels for each layout
    circle_panel = Panel(child=plot_circle, title='Circle layout')
    spring_panel = Panel(child=plot_spring, title='Spring layout')
    random_panel = Panel(child=plot_random, title='Random layout')
    fd_panel = Panel(child=plot_fd, title='Force-Directed layout')

    # Assign NLD panels to Tabs
    tabsNLD_int = Tabs(
        tabs=[circle_panel, spring_panel, fd_panel, random_panel])
    return tabsNLD_int
Ejemplo n.º 12
0
# Make colormap
#palette = tuple([p_county_map for p_county_map in palette]+['#ffffee'])
# palette = Reverse(Inferno256[128:-1:5])
palette = Turbo256[128:-1:5]

CmapAndTicks = make_color_mapper_and_ticks(palette=palette,
                                           low=0,
                                           high=20 * len(palette),
                                           label_format='{:1.0f}')
color_mapper = CmapAndTicks['color_mapper']

color_bar = ColorBar(
    color_mapper=CmapAndTicks['color_mapper'],
    ticker=CmapAndTicks['ticker'],
    formatter=CmapAndTicks['formatter'],
    label_standoff=2,
    border_line_color=None,
    location=(0, 0),
    bar_line_alpha=0.5,
    major_label_text_align='left',
)
# %% Make Buttons for state graph
"""
# %% Make Buttons for state graph
________________________________________________________________________________
"""
buttons = {}
buttons['state_covid_data'] = Toggle(label="State Time History Graph",
                                     visible=False,
                                     button_type='primary')  #
buttons['state_covid_data'].js_on_change(
    'active',
Ejemplo n.º 13
0
def map_create(prot_pop_geo, prot_pop):

    geosource = GeoJSONDataSource(
        geojson=simplejson.dumps(simplejson.loads(prot_pop_geo.to_json())))

    # ----- Raw count map -----

    # initialize figure
    palette = cividis(256)

    hover_a = HoverTool(tooltips=[('Country', '@name'), ('Protests',
                                                         '@protest')])
    color_mapper_a = LogColorMapper(palette=palette,
                                    low=1,
                                    high=prot_pop['protest'].max() + 5,
                                    nan_color='#ffffff')
    color_bar_a = ColorBar(
        color_mapper=color_mapper_a,
        ticker=LogTicker(),
        orientation='horizontal',
        border_line_color=None,
        location=(0, 0),
        label_standoff=8,
        major_label_text_font='Raleway',
        major_label_text_font_size='12pt',
        title='Number of registered Fridays for Future protests',
        title_text_font_style='normal',
        title_text_font='Raleway',
        title_text_font_size='15pt')

    p_a = figure(
        title=
        'The Fridays for Future movement grew to global scale within only 10 months',
        tools=[hover_a,
               ZoomInTool(),
               ZoomOutTool(),
               ResetTool(),
               PanTool()],
        plot_height=600,
        plot_width=980)

    # add patch renderer
    p_a.patches('xs',
                'ys',
                source=geosource,
                fill_color={
                    'field': 'protest',
                    'transform': color_mapper_a
                },
                line_color='black',
                line_width=0.25,
                fill_alpha=1)

    # prettify
    p_a.xgrid.grid_line_color = None
    p_a.ygrid.grid_line_color = None
    p_a.outline_line_color = None
    p_a.axis.visible = False
    p_a.add_layout(color_bar_a, 'below')
    p_a.toolbar.logo = None
    p_a.title.text_font = "Raleway"
    p_a.title.text_font_style = "normal"
    p_a.title.align = 'center'
    p_a.title.text_color = 'black'
    p_a.title.text_font_size = '20pt'

    tab_a = Panel(child=p_a, title="Absolute number")

    # ----- Population adjusted count map -----

    # initialize figure
    hover_b = HoverTool(tooltips=[(
        'Country',
        '@name'), ('Protests per 10 million',
                   '@prot_ptm'), ('Protests',
                                  '@protest'), ('Population', '@population')])
    color_mapper_b = LogColorMapper(
        palette=palette,
        low=prot_pop['prot_ptm'].min(),
        high=float(prot_pop.loc[prot_pop['code'] == 'GRL']['prot_ptm']) + 10,
        nan_color='#ffffff')
    color_bar_b = ColorBar(
        color_mapper=color_mapper_b,
        ticker=LogTicker(),
        orientation='horizontal',
        border_line_color=None,
        location=(0, 0),
        label_standoff=8,
        major_label_text_font='Raleway',
        major_label_text_font_size='12pt',
        title='Number of registered Fridays for Future protests per 10 million',
        title_text_font_style='normal',
        title_text_font='Raleway',
        title_text_font_size='15pt')

    p_b = figure(
        title=
        'The Fridays for Future movement grew to global scale within only 10 months',
        tools=[hover_b,
               ZoomInTool(),
               ZoomOutTool(),
               ResetTool(),
               PanTool()],
        plot_height=600,
        plot_width=980)

    # add patch renderer
    p_b.patches('xs',
                'ys',
                source=geosource,
                fill_color={
                    'field': 'prot_ptm',
                    'transform': color_mapper_b
                },
                line_color='black',
                line_width=0.25,
                fill_alpha=1)

    # prettify
    p_b.xgrid.grid_line_color = None
    p_b.ygrid.grid_line_color = None
    p_b.outline_line_color = None
    p_b.axis.visible = False
    p_b.add_layout(color_bar_b, 'below')
    p_b.toolbar.logo = None
    p_b.title.text_font = "Raleway"
    p_b.title.text_font_style = "normal"
    p_b.title.align = 'center'
    p_b.title.text_color = 'black'
    p_b.title.text_font_size = '20pt'

    tab_b = Panel(child=p_b, title="Population normalized")

    tabs = Tabs(tabs=[tab_a, tab_b])

    return tabs
Ejemplo n.º 14
0
def GDP_PCA_plot(filename=None,
                 threshold=0.015,
                 lowerbound=2.0,
                 upperbound=1.0e4,
                 factor=0.08):
    data = np.load('uploads/' + filename)

    image1 = data.f.image  #-np.median(data.f.image)
    image2 = np.array(image1 * 255 / image1.max(), dtype='uint8')
    image_avg = np.mean(np.partition(image2, int(len(image2) * 0.2)))
    image2[image2 < image_avg] = int(image_avg)
    #H1=cv2.GaussianBlur(image2,(3,3),1.0*np.std(image2))
    H1 = gaussian_filter(image2, factor * np.std(image2), mode='nearest')
    image2 = H1
    blobs_log = blob_log(image2,
                         max_sigma=0.3 * np.std(image2),
                         min_sigma=0.02 * np.mean(image2),
                         num_sigma=20,
                         threshold=threshold,
                         overlap=0.6)
    blobs_log[:, 2] = blobs_log[:, 2] * np.sqrt(2)
    blobs = blobs_log[(blobs_log[:, 2] > lowerbound)
                      & (blobs_log[:, 2] < upperbound)]

    xx = (data.f.X.min(), np.round(data.f.X.max(), -1))
    yy = (data.f.Y.min(), np.round(data.f.Y.max(), -1))
    x_step = (xx[1] - xx[0]) / np.shape(H1)[0]
    y_step = (yy[1] - yy[0]) / np.shape(H1)[1]

    #Number of NV
    height = yy[1] - yy[0]
    width = xx[1] - xx[0]
    total = len(blobs)
    per_nv = round(len(blobs) / float(height * width) * (20 * 20), 2)
    ########################################################
    t = [
        'Original Density Plot,'
        ' Filename=' + filename, 'Gaussian Filtered Density Plot',
        'Total NVs =' + str(total) + ' , NVs per 20x20 pixel area = ' +
        str(per_nv)
    ]

    data_list = [image1, H1, H1]
    color_list = [
        Viridis256, cc.b_linear_bgy_10_95_c74, cc.b_linear_bgy_10_95_c74
    ]
    return_list = []
    return_list.append(head)
    #hover tool hack to work for image function in bokeh.
    ##http://stackoverflow.com/questions/28176949/convert-list-of-tuples-to-structured-numpy-array
    px = np.linspace(xx[0], xx[1], np.shape(H1)[0] / 2)
    py = np.linspace(yy[0], yy[1], np.shape(H1)[1] / 2)
    px = np.array(px, dtype='uint32')
    py = np.array(py, dtype='uint32')
    a = []
    for i in px:
        a.extend(zip(itertools.repeat(i), py))
    dt = np.dtype('int,float')
    X = np.array(a, dtype=dt)
    x1 = X['f0']
    y1 = X['f1']
    ##################################################################
    for i in range(3):
        color_mapper = LogColorMapper(palette=color_list[i], \
                              low=np.mean(data_list[i]), \
                              high=1.0*np.mean(data_list[i])+\
                              2.0*np.std(data_list[i]))


        color_bar = ColorBar(color_mapper=color_mapper,\
                              label_standoff=12, \
                              border_line_color=None, \
                              location=(0,0))


        p1 = figure(plot_width=600, plot_height=600,title=t[i],title_text_font_size='12pt',\
                    x_range=xx,y_range=xx,tools=TOOLS,toolbar_location="below",toolbar_sticky=False,responsive=True)
        p1.square(x1, y1, alpha=1.0)
        p1.image(image=[data_list[i]],
                 color_mapper=color_mapper,
                 dh=yy[1] - yy[0],
                 dw=xx[1] - xx[0],
                 x=xx[0],
                 y=xx[0])
        p1.add_layout(color_bar, 'right')
        if i == 2:
            p1.circle(blobs[:, 1] * x_step + xx[0],
                      blobs[:, 0] * y_step + yy[0],
                      radius=blobs[:, 2] * 1.6,
                      radius_dimension='y',
                      line_color='red',
                      alpha=1.0,
                      line_width=3,
                      fill_color=None)

        p1.title.text_font_size = "11pt"
        p1.xaxis.axis_label_text_font_size = "13pt"
        p1.yaxis.axis_label_text_font_size = "13pt"

        #plots = {'Navy': p1, 'Blue': p2};
        tuple_plot = components(p1)
        #script2, div2 = components(p2);

        return_list.append(list(tuple_plot))

    p=Histogram(blobs[:,2],\
            plot_width=600, plot_height=600,tools=TOOLS,\
            toolbar_location="below",toolbar_sticky=False,\
            responsive=True,\
            title="Distribution of Radii of NV Centers")

    return_list.append(list(components(p)))

    return return_list
Ejemplo n.º 15
0
def bokehSec(data, subject, fname, lat, lon, depth, variabels):
    TOOLS = "hover,crosshair,pan,wheel_zoom,zoom_in,zoom_out,box_zoom,undo,redo,reset,tap,save,box_select,poly_select,lasso_select,"
    w = 1000
    h = 500
    p = []
    data_org = list(data)
    for ind in range(len(data_org)):
        data = data_org[ind]
        bounds = getBounds(variabels[ind])
        paletteName = getPalette(variabels[ind])
        if bounds[0] == None:
            color_mapper = LinearColorMapper(palette=paletteName)
        else:
            color_mapper = LinearColorMapper(palette=paletteName,
                                             low=bounds[0],
                                             high=bounds[1])

        if len(lon) > len(lat):
            p1 = figure(tools=TOOLS,
                        toolbar_location="above",
                        title=subject[ind],
                        plot_width=w,
                        plot_height=h,
                        x_range=(np.min(lon), np.max(lon)),
                        y_range=(np.min(depth), np.max(depth)))
            data = np.nanmean(data, axis=0)
            data = np.transpose(data)
            data = np.squeeze(data)
            p1.xaxis.axis_label = 'Longitude'
            p1.image(image=[data],
                     color_mapper=color_mapper,
                     x=np.min(lon),
                     y=np.max(depth),
                     dw=np.max(lon) - np.min(lon),
                     dh=np.max(depth) - np.min(depth))
        else:
            p1 = figure(tools=TOOLS,
                        toolbar_location="above",
                        title=subject[ind],
                        plot_width=w,
                        plot_height=h,
                        x_range=(np.min(lat), np.max(lat)),
                        y_range=(np.min(depth), np.max(depth)))
            data = np.nanmean(data, axis=1)
            data = np.transpose(data)
            data = np.squeeze(data)
            p1.xaxis.axis_label = 'Latitude'
            '''
            if ind==0:
                data1 = data
            if ind==1:
                data = data / data1
            '''
            p1.image(image=[data],
                     color_mapper=color_mapper,
                     x=np.min(lat),
                     y=np.min(depth),
                     dw=np.max(lat) - np.min(lat),
                     dh=np.max(depth) - np.min(depth))

        p1.yaxis.axis_label = 'depth [m]'
        color_bar = ColorBar(color_mapper=color_mapper,
                             ticker=BasicTicker(),
                             label_standoff=12,
                             border_line_color=None,
                             location=(0, 0))
        p1.add_layout(color_bar, 'right')
        p.append(p1)
    dirPath = 'embed/'
    if not os.path.exists(dirPath):
        os.makedirs(dirPath)
    output_file(dirPath + fname + ".html", title="Regional Map")
    show(column(p))
    return
Ejemplo n.º 16
0
mapper = LinearColorMapper(palette=colors, low=0, high=40)
TOOLS_vitesse = "hover,save,pan,box_zoom,reset,wheel_zoom"
Vitesses = figure(plot_width=597,
                  plot_height=370,
                  x_axis_type='datetime',
                  y_range=DAYS,
                  tools=TOOLS_vitesse)
Vitesses.grid.grid_line_color = None
Vitesses.axis.major_tick_line_color = None
Vitesses.xaxis[0].formatter.days = ['%Hh']
Vitesses.x_range.range_padding = 0

# barre de légende
bar = ColorBar(color_mapper=mapper,
               location=(0, -10),
               major_label_text_font_size="5pt",
               width=5,
               height=335)
Vitesses.add_layout(bar, 'right')
tab_vitesses = Panel(child=Vitesses, title="Vitesses Moyennes")
Vitesses.select_one(HoverTool).tooltips = [
    ('vitesse moyenne', '@rate'),
]

# données du graphe de vitesses
VitessesChart = Vitesses.rect(x='heure',
                              y='Jour',
                              width=1800000,
                              height=1,
                              source=VitesseSource,
                              fill_color={
Ejemplo n.º 17
0
def draw_blocks_incidents(new, traffic):
    '''
    By taking in the incidents' area information, we create a plot with the areas boundaries.
    The colors filled is based on the number of incidents happened in the area.
    If there are more incidents, the color will be darker.
    :param new: the dataframe contains cleaned incidents information by area
    :param traffic: the dataframe will full traffic incidents information
    :param fname: the output filename
    :return: a html file contains the blocks of Los Angeles areas
    '''

    assert isinstance(new, pd.DataFrame)
    assert isinstance(traffic, pd.DataFrame)

    new_area = list(dict(new.groupby('Area_Name')['Area_Name'].count()))
    incidents_counter = [0] * len(new_area)

    for i in range(traffic.shape[0]):
        for j in range(len(new_area)):
            if (traffic['lon'][i] >= new['min_lon'][j]) & (traffic['lon'][i] <= new['max_lon'][j]) & (
                    traffic['lat'][i] >= new['min_lat'][j]) & (traffic['lat'][i] <= new['max_lat'][j]):
                incidents_counter[j] += 1

    area_dict = dict(zip(new_area, incidents_counter))
    area_dict['Southeast'] += 3187
    area_dict['West LA'] += 1361
    sorted_by_value = sorted(area_dict.items(), key=lambda kv: kv[1], reverse=True)

    checklist = []
    for i in sorted_by_value:
        checklist.append(i[0])

    max_lons = []
    min_lons = []
    max_lats = []
    min_lats = []

    for i in checklist:
        max_lons.append(float(new[new['Area_Name'] == i]['max_lon']))
        min_lons.append(float(new[new['Area_Name'] == i]['min_lon']))
        max_lats.append(float(new[new['Area_Name'] == i]['max_lat']))
        min_lats.append(float(new[new['Area_Name'] == i]['min_lat']))

    io.output_notebook()

    palettes = inferno(120)
    final_palettes = []
    count = 0
    for i in palettes:
        count += 1
        if count % 10 == 0:
            final_palettes.append(i)

    #all_palettes['Reds'][9]

    p = figure(plot_width=450, plot_height=400)
    p.quad(top=max_lons, bottom=min_lons, left=min_lats, right=max_lats, color=final_palettes, fill_alpha=0.8)

    color_mapper = LogColorMapper(palette=final_palettes)
    color_bar = ColorBar(color_mapper=color_mapper, location=(0, 0))

    p.add_layout(color_bar, 'left')

    return show(p)
Ejemplo n.º 18
0
p1.legend.location = "bottom_right"
p1.legend.title = 'AOI'
p1.y_range.flipped = True

# In[10]:

# fixation heatmap
source_heat = ColumnDataSource(
    data=dict(x=[], y=[], color=[], user=[], gradient=[]))

mapper = LinearColorMapper(palette="Turbo256",
                           low=33,
                           high=1200,
                           low_color="blue",
                           high_color="red")
color_bar = ColorBar(color_mapper=mapper, width=8, location=(0, 0))

p2 = figure(title="Fixation heat map",
            plot_width=p1.plot_width,
            plot_height=p1.plot_width,
            tools=TOOLS,
            tooltips=TOOLTIPS,
            x_range=p1.x_range,
            y_range=p1.y_range,
            sizing_mode="scale_both",
            x_axis_label='x-axis',
            y_axis_label='y-axis')
p2.circle(x="x",
          y="y",
          source=source,
          size=10,
Ejemplo n.º 19
0
    def _contour_data(self):
        """
        Create a contour plot.

        Parameters
        ----------
        None

        Returns
        -------
        Bokeh Image Plot
        """
        resolution = self.resolution
        # Output data array initialization
        y_data = np.zeros((resolution, resolution, self.num_outputs))
        self.input_point_list = [
            point.value for point in self.slider_dict.values()
        ]

        # Pass the dict to make predictions and then reshape the output to
        # (resolution, resolution, number of outputs)
        y_data[:, :, :] = self._make_predictions(
            self._contour_data_calcs()).reshape(
                (resolution, resolution, self.num_outputs))
        # Use the output variable to pull the correct column of data from the predicted
        # data (y_data)
        self.Z = y_data[:, :, self.output_variable]
        # Reshape it to be 2D
        self.Z = self.Z.reshape(resolution, resolution)

        # Update the data source with new data
        self.contour_plot_source.data = dict(z=[self.Z])

        # Min to max of training data
        self.contour_x_range = xlins = self.xlins_mesh
        self.contour_y_range = ylins = self.ylins_mesh

        # Color bar formatting
        color_mapper = LinearColorMapper(palette="Viridis11",
                                         low=np.amin(self.Z),
                                         high=np.amax(self.Z))
        color_bar = ColorBar(color_mapper=color_mapper,
                             ticker=BasicTicker(),
                             label_standoff=12,
                             location=(0, 0))

        # Contour Plot
        self.contour_plot = contour_plot = figure(
            match_aspect=False,
            tooltips=[(self.x_input_select.value, "$x"),
                      (self.y_input_select.value, "$y"),
                      (self.output_select.value, "@z")],
            tools='')
        contour_plot.x_range.range_padding = 0
        contour_plot.y_range.range_padding = 0
        contour_plot.plot_width = 600
        contour_plot.plot_height = 500
        contour_plot.xaxis.axis_label = self.x_input_select.value
        contour_plot.yaxis.axis_label = self.y_input_select.value
        contour_plot.min_border_left = 0
        contour_plot.add_layout(color_bar, 'right')
        contour_plot.x_range = Range1d(min(xlins), max(xlins))
        contour_plot.y_range = Range1d(min(ylins), max(ylins))
        contour_plot.image(image='z',
                           source=self.contour_plot_source,
                           x=min(xlins),
                           y=min(ylins),
                           dh=(max(ylins) - min(ylins)),
                           dw=(max(xlins) - min(xlins)),
                           palette="Viridis11")

        # Adding training data points overlay to contour plot
        if self.is_structured_meta_model:
            data = self._structured_training_points()
        else:
            data = self._unstructured_training_points()

        if len(data):
            # Add training data points overlay to contour plot
            data = np.array(data)
            if self.is_structured_meta_model:
                self.contour_training_data_source.data = dict(
                    x=data[:, 0],
                    y=data[:, 1],
                    z=self.meta_model.training_outputs[
                        self.output_select.value].flatten())
            else:
                self.contour_training_data_source.data = dict(
                    x=data[:, 0],
                    y=data[:, 1],
                    z=self.meta_model._training_output[
                        self.output_select.value])

            training_data_renderer = self.contour_plot.circle(
                x='x',
                y='y',
                source=self.contour_training_data_source,
                size=5,
                color='white',
                alpha=0.50)

            self.contour_plot.add_tools(
                HoverTool(renderers=[training_data_renderer],
                          tooltips=[
                              (self.x_input_select.value + " (train)", '@x'),
                              (self.y_input_select.value + " (train)", '@y'),
                              (self.output_select.value + " (train)", '@z'),
                          ]))

        return self.contour_plot
Ejemplo n.º 20
0
                                 nan_color='white')
plot = figure(title='Temperature @ 1km, hour 1',
              x_axis_label='Longitude',
              y_axis_label='Latitude',
              x_range=(0, 500),
              y_range=(0, 500),
              toolbar_location=None)
plot.image(image=[np.flipud(image)],
           color_mapper=color_mapper,
           dh=[500],
           dw=[500],
           x=[0],
           y=[0])
color_bar = ColorBar(title='T [ºC]',
                     color_mapper=color_mapper,
                     ticker=BasicTicker(),
                     label_standoff=12,
                     border_line_color=None,
                     location=(0, 0))
plot.add_layout(color_bar, 'left')
output_file('task4.html')
show(plot)

##task 5
U = get_xy(data['Uf01'], 5)
V = get_xy(data['Vf01'], 5)
W = get_xy(data['Wf01'], 5)
#U=get_xy(data['Uf37'], 50) # reproduce plot in assignment
#V=get_xy(data['Vf37'], 50)
#W=get_xy(data['Wf37'], 50)

x_start = np.zeros(100, dtype='float')
Ejemplo n.º 21
0
def contour_plot_bokeh(
        model,
        xlabel=None,
        ylabel=None,
        main=None,
        xlim=(-3.2, 3.2),
        ylim=(-3.2, 3.2),
        colour_function="terrain",
        show=True,
        show_expt_data=True,
        figsize=(10, 10),
        dpi=50,
        other_factors=None,
):

    # TODO: show labels of contour plot

    # https://stackoverflow.com/questions/33533047/how-to-make-a-contour-plot-in-python-using-bokeh-or-other-libs

    dpi_max = dpi**3.5
    N = min(dpi, np.power(dpi_max, 0.5))

    h_grid = np.linspace(xlim[0], xlim[1], num=N)
    v_grid = np.linspace(ylim[0], ylim[1], num=N)
    H, V = np.meshgrid(h_grid, v_grid)
    h_grid, v_grid = H.ravel(), V.ravel()

    pure_factors = model.get_factor_names(level=1)
    if xlabel is None:
        xlabel = pure_factors[0]
    else:
        xlabel = str(xlabel)

    if ylabel is None:
        ylabel = pure_factors[1]
    else:
        ylabel = str(ylabel)

    kwargs = {xlabel: h_grid, ylabel: v_grid}
    if other_factors is not None and isinstance(other_factors, dict):
        kwargs = kwargs.update(other_factors)

    # Look at which factors are included, and pop them out. The remaining
    # factors are specified at their zero level

    unspecified_factors = [i for i in pure_factors if i not in kwargs.keys()]
    for factor in unspecified_factors:
        kwargs[factor] = np.zeros_like(h_grid)

    assert sorted(kwargs.keys()) == sorted(pure_factors), ("Not all factors "
                                                           "were specified.")
    Z = predict(model, **kwargs)
    Z = Z.values.reshape(N, N)
    z_min, z_max = Z.min(), Z.max()
    levels = np.linspace(z_min, z_max, N)

    import matplotlib
    import matplotlib.pyplot as plt
    from matplotlib.pyplot import clabel, contour

    matplotlib.use("Agg")
    # Turn interactive plotting off
    plt.ioff()
    CS = contour(H, V, Z, levels=levels, linestyles="dotted")
    clabel(CS, inline=True, fontsize=10, fmt="%1.0f")
    # contour_labels = [(float(q._x), float(q._y), float(q._text))\
    #                                                 for q in CS.labelTexts]

    # Convert the Matplotlib colour mapper to Bokeh
    # https://stackoverflow.com/questions/49931311/using-matplotlibs-colormap-for-bokehs-color-bar
    mapper = getattr(cm, colour_function)
    colours = (255 * mapper(range(256))).astype("int")
    colour_palette = [RGB(*tuple(rgb)).to_hex() for rgb in colours]
    color_mapper = LinearColorMapper(palette=colour_palette,
                                     low=z_min,
                                     high=z_max)

    # Another alternative:
    # https://stackoverflow.com/questions/35315259/using-colormap-with-bokeh-scatter
    # colors = ["#%02x%02x%02x" % (int(r), int(g), int(b)) for \
    #        r, g, b, _ in 255*mpl.cm.viridis(mpl.colors.Normalize()(radii))]

    p = figure(
        x_range=xlim,
        y_range=ylim,
        # https://github.com/bokeh/bokeh/issues/2351
        tools="pan,wheel_zoom,box_zoom,box_select,lasso_select,reset,save",
    )
    # Create the image layer
    source = {"Xax": [h_grid], "Yax": [v_grid], "predictions": [Z]}
    h_image = p.image(
        source=source,
        image="predictions",
        x=xlim[0],
        y=ylim[0],
        dw=xlim[1] - xlim[0],
        dh=ylim[1] - ylim[0],
        color_mapper=color_mapper,
        global_alpha=0.5,  # with some transparency
        name="contour_image",
    )
    h1 = HoverTool(
        tooltips=[
            (xlabel, "@{Xax}{0.4g}"),
            (ylabel, "@{Yax}{0.4f}"),
            ("Predicted", "@{predictions}{0.4g}"),
        ],
        renderers=[h_image],
        formatters={
            "Predicted": "printf",
            xlabel: "printf",
            ylabel: "printf"
        },
    )

    color_bar = ColorBar(
        color_mapper=color_mapper,
        major_label_text_font_size="8pt",
        ticker=BasicTicker(max_interval=(z_max - z_min) / N * 2),
        formatter=PrintfTickFormatter(format="%.2f"),
        label_standoff=6,
        border_line_color=None,
        location=(0, 0),
    )

    p.add_layout(color_bar, "right")

    # Contour lines using Scipy:
    # scaler_y = (ylim[1] - ylim[0]) / (N - 1)
    # scaler_x = (xlim[1] - xlim[0]) / (N - 1)
    # for level in levels:
    # contours = measure.find_contours(Z, level)
    # for contour in contours:
    # x = contour[:, 1] * scaler_y + ylim[0]
    # y = contour[:, 0] * scaler_x + xlim[0]

    for _, cccontour in enumerate(CS.allsegs):
        if cccontour:
            x = cccontour[0][:, 0]
            y = cccontour[0][:, 1]
            p.line(x, y, line_dash="dashed", color="darkgrey", line_width=1)

    # TODO: bigger experimental markers
    # TODO: hover for the data point shows the factor settings for the data point

    if show_expt_data:

        source = ColumnDataSource(data=dict(
            x=model.data[xlabel],
            y=model.data[ylabel],
            output=model.data[model.get_response_name()].to_list(),
        ))
        h_expts = p.circle(
            x="x",
            y="y",
            color="black",
            source=source,
            # linestyle='',
            # marker='o',
            size=10,
            line_width=2,
            name="experimental_points",
        )
        # custom tooltip for the experimental points
        h2 = HoverTool(
            tooltips=[
                (xlabel, "$x{0.4g}"),
                (ylabel, "$y{0.4g}"),
                ("Actual value", "@{output}{0.4g}"),  # why not working???
            ],
            renderers=[h_expts],
            formatters={
                "Actual value": "printf",
                xlabel: "printf",
                ylabel: "printf"
            },
        )
        h2.point_policy = "snap_to_data"
        h2.line_policy = "none"

    # Axis labels:
    p.xaxis.axis_label_text_font_size = "14pt"
    p.xaxis.axis_label = xlabel
    p.xaxis.major_label_text_font_size = "14pt"
    p.xaxis.axis_label_text_font_style = "bold"
    p.xaxis.bounds = (xlim[0], xlim[1])

    p.yaxis.major_label_text_font_size = "14pt"
    p.yaxis.axis_label = ylabel
    p.yaxis.axis_label_text_font_size = "14pt"
    p.yaxis.axis_label_text_font_style = "bold"
    p.yaxis.bounds = (ylim[0], ylim[1])

    # Add the hover tooltips:
    p.add_tools(h1)
    p.add_tools(h2)

    if show:
        show_plot(p)
    return p
Ejemplo n.º 22
0
def scatter2D(
        x,
        y,
        z,
        vmin=None,
        vmax=None,
        cmax='red',
        cmin='blue',
        cundef='grey',
        cpalete_size=250,
        ctransform='log',
        radii=1.,
        lcolor='black',
        title='Scatterplot',
        TOOLS='resize,crosshair,pan,wheel_zoom,box_zoom,reset,tap,previewsave,box_select,poly_select,lasso_select',
        xlabel='X',
        ylabel='Y',
        alpha=0.8,
        outvar='__inds'):
    """Plot a 2D scaterplot, e.g. data location with bokeh, and allows manual selection of data.


    Parameters
    ----------
        x, y  :  array of floats. Coordinates
        z     :  array of floats. Variable for color
        vmin, vmax : floats (Optional, default None, that is data max and min). Value minimum and maximum for colour scale.
        cmax : string with valid bokeh colour (Optional, default 'red'). Color corresponding to vmax or above
        cmin : string with valid bokeh colour (Optional, default 'blue'). Color corresponding to vmin
        cundef : string with valid bokeh colour (Optional, default 'grey'). Color corresponding to values < vmin and undefined
        cpalete_size : integer (Optional default 250). Size of the colour palete/scale
        ctransform : string ( Optional, default 'log'). If == 'log' will use log scale to asign colors, otherwise will use linear scale
        radii : float (Optional, default 1.). Size of the circles plotted
        lcolor: string (ptional, default 'black'). Color of the circle outline.
        title: string (Optional, default 'Scatterplot'). Title of the plot
        TOOLS: string (Optional, default 'resize,crosshair,pan,wheel_zoom,box_zoom,reset,tap,previewsave,box_select,poly_select,lasso_select'). Tools shown in the plot.
        xlabel: string (Optional, default 'X'). X axis label
        ylabel: string (Optional, default 'Y'). Y axis label
        alpha: float (Optional, default 0.8). Transparency of circles background
        outvar: string (Optional, default '__inds'). Name of the callback variable. Each time you select points in the scatterplot this variable will be updated.


    Note
    -------
    This function will create a new variable defined by outvar, e.g. '__inds', the firts time you select points. This variable will be overwritten if it already exist.
    This variable may be overwritten by selecting points in a different plot with same value in the parameter outvar.

    The selection variable is updated in your python kernel from a javascript (web brouser) using a calling back function.


    Example
    -------
    >>> pygslib.plothtml.scatter2D(
              # data
              x= mydata['Xlocation'],
              y= mydata['Ylocation'],
              z= mydata['Primary'],
              # vmin and max for formating
              vmin=0.1,
              vmax=30,
              # parameters for color
              cmax = 'red',
              cmin = 'blue',
              cundef='grey',
              cpalete_size=300,
              ctransform = 'linear',
              #parameter for circle size
              radii=0.5,
              # line color
              lcolor= 'black',
              # parameters for plot
              title='Scatterplot',
              TOOLS='resize,crosshair,pan,wheel_zoom,box_zoom,reset,tap,previewsave,box_select,poly_select,lasso_select',
              xlabel='X',
              ylabel='Y',
              alpha=0.9,
              # call back variable
              outvar='__inds')
    >>> print " Select some datapoints, e.g. using the tool lasso "
    >>> print mydata.iloc[__inds,:]

    """

    #prepare data
    df = pd.DataFrame({'x': x, 'y': y, 'z': z})
    df['radii'] = radii
    df['alpha'] = alpha
    df['lcolor'] = lcolor

    if vmin is None:
        vmin = z.min()
    if vmax is None:
        vmax = z.max()

    assert vmin < vmax

    source = ColumnDataSource(df)

    # create a palete.
    colourscale = pygslib.charttable.Leyend_num(vmin=vmin,
                                                vmax=vmax,
                                                cmax=cmax,
                                                cmin=cmin,
                                                undef=cundef,
                                                nval=cpalete_size,
                                                convert='HEX')
    palete = colourscale.c.tolist()

    # create a mapper
    if ctransform == 'log':
        assert vmin > 0 and vmax > 0, "vmin/vmax <=0 and using log transform"
        mapper = LogColorMapper(palette=palete, low=vmin, high=vmax)
    else:
        mapper = LinearColorMapper(palette=palete, low=vmin, high=vmax)

    mapper.low_color = cundef
    mapper.high_color = cmax

    # create figure
    p = bkplt.figure(title=title, tools=TOOLS, toolbar_location='above')
    p.xaxis.axis_label = xlabel
    p.yaxis.axis_label = ylabel

    # colorbar
    color_bar = ColorBar(color_mapper=mapper, location=(0, 0))

    # plot
    p.scatter(source=source,
              x="x",
              y="y",
              radius='radii',
              fill_color={
                  'field': 'z',
                  'transform': mapper
              },
              fill_alpha='alpha',
              line_color='lcolor')

    p.add_layout(color_bar, 'right')

    source.callback = CustomJS(args=dict(p=p),
                               code="""
            var inds = cb_obj.get('selected')['1d'].indices;
            var d1 = cb_obj.get('data');
            console.log(d1)
            var kernel = IPython.notebook.kernel;
            IPython.notebook.kernel.execute("{} = " + inds);
            """.format(outvar))

    bkplt.show(p)
Ejemplo n.º 23
0
def hexbin_viz(
    df: pd.DataFrame,
    x: str,
    y: str,
    plot_width: int,
    plot_height: int,
    tile_size: Optional[float] = None,
) -> Panel:
    """
    Render a hexbin plot
    """
    # pylint: disable=too-many-arguments,too-many-locals
    xmin, xmax = df[x].min(), df[x].max()
    ymin, ymax = df[y].min(), df[y].max()
    if tile_size is None:
        tile_size = (xmax - xmin) / 25
    title = f"{y} by {x}"
    aspect_scale = (ymax - ymin) / (xmax - xmin)
    bins = hexbin(
        x=df[x],
        y=df[y],
        size=tile_size,
        orientation="flattop",
        aspect_scale=aspect_scale,
    )
    fig = figure(
        title=title,
        tools=[],
        match_aspect=False,
        background_fill_color="#f5f5f5",
        toolbar_location=None,
        plot_width=plot_width,
        plot_height=plot_height,
    )

    palette = list(reversed(viridis(256)))
    rend = fig.hex_tile(
        q="q",
        r="r",
        size=tile_size,
        line_color=None,
        source=bins,
        orientation="flattop",
        fill_color=linear_cmap(
            field_name="counts",
            palette=palette,
            low=min(bins.counts),
            high=max(bins.counts),
        ),
        aspect_scale=aspect_scale,
    )
    fig.add_tools(
        HoverTool(
            tooltips=[("Count", "@counts")],
            renderers=[rend],
        ))
    mapper = LinearColorMapper(palette=palette,
                               low=min(bins.counts),
                               high=max(bins.counts))
    color_bar = ColorBar(color_mapper=mapper, width=8, location=(0, 0))
    color_bar.label_standoff = 8
    fig.add_layout(color_bar, "right")
    tweak_figure(fig, "hex")
    fig.xaxis.ticker = list(np.linspace(xmin, xmax, 10))
    fig.yaxis.ticker = list(np.linspace(ymin, ymax, 10))
    fig.xaxis.axis_label = x
    fig.yaxis.axis_label = y

    return Panel(child=fig, title="hexbin plot")
Ejemplo n.º 24
0
plot = make_plot()

tab_doc = Panel(child=column(row(select_feature), row(plot), row(slider_time)), title="Лікарі")
tab_bed = Panel(child=column(row(select_feature), row(plot), row(slider_time)), title="Ліжка")
tab_equip = Panel(child=column(row(select_feature), row(plot), row(slider_time)), title="Обладнання")
tabs = Tabs(tabs=[tab_doc, tab_bed, tab_equip], name='tabs_custom')

# label_figures = LabelSet(x='centr_x', y='centr_y', text=select_feature.value, x_offset=5, y_offset=-10,
#                          source=geosource, render_mode='canvas', text_font_size='12px', text_align='left')
# plot.add_layout(label_figures)

color_bar = ColorBar(color_mapper=color_mapper,
                     label_standoff=8,
                     width=250, height=10,
                     border_line_color=None,
                     background_fill_color='#f7fbff',
                     location=(0, 0),
                     orientation='horizontal',
                     major_label_overrides=
                     make_tick_labels(n=get_max_feature_value_on_day(select_feature.value,
                                                                     slider_time.value_as_date)))
plot.add_layout(color_bar, 'above')

labels = LabelSet(x='centr_x', y='centr_y', text='ADM1_UA',
                  x_offset=5, y_offset=5, source=geosource, render_mode='canvas', text_font_size='8px',
                  text_align='left')
#plot.add_layout(labels)


def update_legend_color_bar(feature, day):
    new_max_color_value = get_max_feature_value_on_day(feature, day)
    tick_labels = make_tick_labels(new_max_color_value)
Ejemplo n.º 25
0
def calendar_plot(data, field='ret'):
    """
    return a calendar plot
    data
        dataframe with year and month columns
    field
        field to plot values
    Note
    -----
    Prototype copied from bokeh gallery
    https://bokeh.pydata.org/en/latest/docs/gallery/unemployment.html
    """
    from math import pi
    from bokeh.models import LinearColorMapper, BasicTicker, PrintfTickFormatter, ColorBar
    from bokeh.plotting import figure
    from bokeh.palettes import Spectral
    df = data.copy()
    # Type conversion
    df['year'] = df.year.astype('str')
    df['month'] = df.month.astype('str')
    years = list(df.year.unique())
    months = [str(x) for x in range(12, 0, -1)]
    colors = list(reversed(Spectral[6]))
    mapper = LinearColorMapper(palette=colors,
                               low=df[field].min(),
                               high=df[field].max())
    TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
    p = figure(title="Calendar Plot",
               x_range=years,
               y_range=list(reversed(months)),
               x_axis_location="above",
               plot_width=1000,
               plot_height=600,
               tools=TOOLS,
               toolbar_location='below',
               tooltips=[('date', '@year-@month'),
                         ('return', '@{}'.format(field))])
    # Axis settings
    p.grid.grid_line_color = None
    p.axis.axis_line_color = None
    p.axis.major_tick_line_color = None
    p.axis.major_label_text_font_size = "10pt"
    p.axis.major_label_standoff = 0
    p.xaxis.major_label_orientation = pi / 3

    p.rect(x="year",
           y="month",
           width=1,
           height=1,
           source=df,
           fill_color={
               'field': field,
               'transform': mapper
           },
           line_color='black',
           line_width=0.5,
           line_alpha=0.3)

    color_bar = ColorBar(color_mapper=mapper,
                         major_label_text_font_size="8pt",
                         ticker=BasicTicker(desired_num_ticks=len(colors)),
                         formatter=PrintfTickFormatter(format="%d%%"),
                         label_standoff=6,
                         border_line_color=None,
                         location=(0, 0))
    p.add_layout(color_bar, 'right')
    return p
Ejemplo n.º 26
0
		def helper(obs: Observable, plot=None):
			# Domain-specific rendering
			if isinstance(obs, GraphObservable):
				if plot is None:
					plot = figure(x_range=self.x_rng, y_range=self.y_rng, tooltips=[], width=self.plot_width, height=self.plot_height) 
				plot.axis.visible = False
				plot.xgrid.grid_line_color = None
				plot.ygrid.grid_line_color = None
				renderer = from_networkx(G, layout)
				plot.renderers.append(renderer)
				plot.toolbar_location = None

				if obs.Gd is GraphDomain.nodes: 
					plot.add_tools(HoverTool(tooltips=[('value', '@value'), ('node', '@node')]))
					plot.renderers[0].node_renderer.data_source.data['node'] = list(map(str, items[0].G.nodes()))
					plot.renderers[0].node_renderer.data_source.data['value'] = obs.y 
					cmap = LinearColorMapper(palette=self.node_palette, low=self.node_rng[0], high=self.node_rng[1])
					self.node_cmaps[obs.plot_id] = cmap
					if isinstance(obs, gds):
						plot.renderers[0].node_renderer.data_source.data['thickness'] = [3 if (x in obs.X_dirichlet or x in obs.X_neumann) else 1 for x in obs.X] 
						plot.renderers[0].node_renderer.glyph = Ellipse(height=self.node_size, width=self.node_size, fill_color=field('value', cmap), line_width='thickness')
					else:
						plot.renderers[0].node_renderer.glyph = Ellipse(height=self.node_size, width=self.node_size, fill_color=field('value', cmap))
					if self.colorbars:
						cbar = ColorBar(color_mapper=cmap, ticker=BasicTicker(), title='node')
						cbar.major_label_text_font_size = "15pt"
						plot.add_layout(cbar, 'right')
				elif obs.Gd is GraphDomain.edges:
					plot.add_tools(HoverTool(tooltips=[('value', '@value'), ('edge', '@edge')]))
					self.prep_layout_data(obs, G, layout)
					obs.arr_source.data['edge'] = list(map(str, items[0].G.edges()))
					self.draw_arrows(obs, obs.y)
					plot.renderers[0].edge_renderer.data_source.data['value'] = obs.arr_source.data['value']
					cmap = LinearColorMapper(palette=self.edge_palette, low=self.edge_rng[0], high=self.edge_rng[1])
					self.edge_cmaps[obs.plot_id] = cmap
					arrows = Patches(xs='xs', ys='ys', fill_color=field('value', cmap))
					plot.add_glyph(obs.arr_source, arrows)
					if self.colorbars:
						cbar = ColorBar(color_mapper=cmap, ticker=BasicTicker(), title='edge')
						cbar.major_label_text_font_size = "15pt"
						plot.add_layout(cbar, 'right')
					if self.edge_colors:
						plot.renderers[0].edge_renderer.glyph = MultiLine(line_width=5, line_color=field('value', cmap))
					elif isinstance(obs, gds):
						plot.renderers[0].edge_renderer.data_source.data['thickness'] = [3 if (x in obs.X_dirichlet or x in obs.X_neumann) else 1 for x in obs.X] 
						plot.renderers[0].edge_renderer.glyph = MultiLine(line_width='thickness')
				elif obs.Gd is GraphDomain.faces:
					plot.add_tools(HoverTool(tooltips=[('value', '@value'), ('face', '@face')]))
					cmap = LinearColorMapper(palette=self.face_palette, low=self.face_rng[0], high=self.face_rng[1])
					self.face_cmaps[obs.plot_id] = cmap
					obs.face_source = ColumnDataSource()
					xs = [[orig_layout[n][0] for n in f] for f in obs.faces]
					ys = [[orig_layout[n][1] for n in f] for f in obs.faces]
					if hasattr(obs.G, 'rendered_faces'): # Hacky
						xs = [xs[i] for i in obs.G.rendered_faces]
						ys = [ys[i] for i in obs.G.rendered_faces]
					obs.face_source.data['xs'] = xs
					obs.face_source.data['ys'] = ys
					obs.face_source.data['value'] = np.zeros(len(xs))
					faces = Patches(xs='xs', ys='ys', fill_color=field('value', cmap), line_color='#FFFFFF', line_width=2)
					plot.add_glyph(obs.face_source, faces)
					if self.face_orientations:
						# TODO: only works for convex faces
						obs.centroid_x, obs.centroid_y = np.array([np.mean(row) for row in xs]), np.array([np.mean(row) for row in ys])
						obs.radius = 0.3 * np.array([min([np.sqrt((xs[i][j] - obs.centroid_x[i])**2 + (ys[i][j] - obs.centroid_y[i])**2) for j in range(len(xs[i]))]) for i in range(len(xs))])
						height = 2/5 * obs.radius
						arrows_ys = np.stack((obs.centroid_y-obs.radius, obs.centroid_y-obs.radius+height/2, obs.centroid_y-obs.radius-height/2), axis=1)
						obs.face_source.data['centroid_x'] = obs.centroid_x
						obs.face_source.data['centroid_y'] = obs.centroid_y
						obs.face_source.data['radius'] = obs.radius
						obs.face_source.data['arrows_ys'] = (arrows_ys + 0.01).tolist()
						self.draw_face_orientations(obs, cmap)
						arcs = Arc(x='centroid_x', y='centroid_y', radius='radius', start_angle=-0.9, end_angle=4.1, line_color=field('arrow_color', cmap))
						arrows = Patches(xs='arrows_xs', ys='arrows_ys', fill_color=field('arrow_color', cmap), line_color=field('arrow_color', cmap))
						plot.add_glyph(obs.face_source, arcs)
						plot.add_glyph(obs.face_source, arrows)
					if self.colorbars:
						cbar = ColorBar(color_mapper=cmap, ticker=BasicTicker(), title='face')
						cbar.major_label_text_font_size = "15pt"
						plot.add_layout(cbar, 'right')
				else:
					raise Exception('unknown graph domain.')
			elif isinstance(obs, PointObservable):
				plot = figure(width=self.plot_width, height=self.plot_height)
				plot.add_tools(HoverTool(tooltips=[('time', '@t'), ('value', '@value')]))
				plot.toolbar_location = None
				plot.x_range.follow = 'end'
				plot.x_range.follow_interval = 10.0
				plot.x_range.range_padding = 0
				plot.xaxis.major_label_text_font_size = "15pt"
				plot.xaxis.axis_label = 'Time'
				plot.yaxis.major_label_text_font_size = "15pt"
				plot.y_range.range_padding_units = 'absolute'
				plot.y_range.range_padding = obs.render_params['min_res'] / 2
				obs.src = ColumnDataSource({'t': [], 'value': []})
				glyph = Line(x='t', y='value')
				plot.add_glyph(obs.src, glyph)
				# plot.line('t', 'value', line_color='black', source=obs.src)
			elif isinstance(obs, VectorObservable):
				plot = figure(width=self.plot_width, height=self.plot_height, y_range=obs.domain)
				plot.add_tools(HoverTool(tooltips=[('time', '@t'), ('value', '@val'), ('y', '@y')]))
				plot.toolbar_location = None
				plot.x_range.follow = 'end'
				plot.x_range.follow_interval = 10.0
				plot.x_range.range_padding = 0
				# plot.xaxis.major_label_text_font_size = "15pt"
				# plot.xaxis.axis_label = 'Time'
				# plot.yaxis.major_label_text_font_size = "15pt"
				obs.src = ColumnDataSource({'t': [], 'y': [], 'w': [], 'val': []})
				obs.cmap = LinearColorMapper(palette=self.vec_palette, low=0, high=1)
				obs.last_t = obs.t
				plot.rect(x='t', y='y', width='w', height=1, source=obs.src, line_color=None, fill_color=field('val', obs.cmap))
				if self.colorbars:
					cbar = ColorBar(color_mapper=obs.cmap, ticker=BasicTicker(), title='value')
					cbar.major_label_text_font_size = "15pt"
					plot.add_layout(cbar, 'right')
			else:
				raise Exception('unknown observable type: ', obs)
			return plot
Ejemplo n.º 27
0
def geoplot(
    gdf_in,
    geometry_column="geometry",
    figure=None,
    figsize=None,
    title="",
    xlabel="Longitude",
    ylabel="Latitude",
    xlim=None,
    ylim=None,
    color="blue",
    colormap=None,
    colormap_uselog=False,
    colormap_range=None,
    category=None,
    dropdown=None,
    slider=None,
    slider_range=None,
    slider_name="",
    show_colorbar=True,
    colorbar_tick_format=None,
    xrange=None,
    yrange=None,
    hovertool=True,
    hovertool_columns=[],
    hovertool_string=None,
    simplify_shapes=None,
    tile_provider="CARTODBPOSITRON_RETINA",
    tile_provider_url=None,
    tile_attribution="",
    tile_alpha=1,
    panning=True,
    zooming=True,
    toolbar_location="right",
    show_figure=True,
    return_figure=True,
    return_html=False,
    legend=True,
    webgl=True,
    **kwargs,
):
    """Doc-String: TODO"""

    # Imports:
    import bokeh.plotting
    from bokeh.plotting import show
    from bokeh.models import (
        HoverTool,
        LogColorMapper,
        LinearColorMapper,
        GeoJSONDataSource,
        WheelZoomTool,
        ColorBar,
        BasicTicker,
        LogTicker,
        Select,
        Slider,
        ColumnDataSource,
    )
    from bokeh.models.callbacks import CustomJS
    from bokeh.models.widgets import Dropdown
    from bokeh.palettes import all_palettes
    from bokeh.layouts import row, column

    # Make a copy of the input geodataframe:
    gdf = gdf_in.copy()

    # Check layertypes:
    if type(gdf) != pd.DataFrame:
        layertypes = []
        if "Point" in str(gdf.geom_type.unique()):
            layertypes.append("Point")
        if "Line" in str(gdf.geom_type.unique()):
            layertypes.append("Line")
        if "Polygon" in str(gdf.geom_type.unique()):
            layertypes.append("Polygon")
        if len(layertypes) > 1:
            raise Exception(
                f"Can only plot GeoDataFrames/Series with single type of geometry (either Point, Line or Polygon). Provided is a GeoDataFrame/Series with types: {layertypes}"
            )
    else:
        layertypes = ["Point"]

    # Get and check provided parameters for geoplot:
    figure_options = {
        "title": title,
        "x_axis_label": xlabel,
        "y_axis_label": ylabel,
        "plot_width": 600,
        "plot_height": 400,
        "toolbar_location": toolbar_location,
        "active_scroll": "wheel_zoom",
        "x_axis_type": "mercator",
        "y_axis_type": "mercator",
    }
    if not figsize is None:
        width, height = figsize
        figure_options["plot_width"] = width
        figure_options["plot_height"] = height
    if webgl:
        figure_options["output_backend"] = "webgl"

    if type(gdf) != pd.DataFrame:
        # Convert GeoDataFrame to Web Mercator Projection:
        gdf.to_crs(epsg=3857, inplace=True)

        # Simplify shapes if wanted:
        if isinstance(simplify_shapes, numbers.Number):
            if layertypes[0] in ["Line", "Polygon"]:
                gdf[geometry_column] = gdf[geometry_column].simplify(
                    simplify_shapes)
        elif not simplify_shapes is None:
            raise ValueError(
                "<simplify_shapes> parameter only accepts numbers or None.")

    # Check for category, dropdown or slider (choropleth map column):
    category_options = 0
    if not category is None:
        category_options += 1
        category_columns = [category]
    if not dropdown is None:
        category_options += 1
        category_columns = dropdown
    if not slider is None:
        category_options += 1
        category_columns = slider
    if category_options > 1:
        raise ValueError(
            "Only one of <category>, <dropdown> or <slider> parameters is allowed to be used at once."
        )

    # Check for category (single choropleth plot):
    if category is None:
        pass
    elif isinstance(category, (list, tuple)):
        raise ValueError(
            "For <category>, please provide an existing single column of the GeoDataFrame."
        )
    elif category in gdf.columns:
        pass
    else:
        raise ValueError(
            f"Could not find column '{category}' in GeoDataFrame. For <category>, please provide an existing single column of the GeoDataFrame."
        )

    # Check for dropdown (multiple choropleth plots via dropdown selection):
    if dropdown is None:
        pass
    elif not isinstance(dropdown, (list, tuple)):
        raise ValueError(
            "For <dropdown>, please provide a list/tuple of existing columns of the GeoDataFrame."
        )
    else:
        for col in dropdown:
            if col not in gdf.columns:
                raise ValueError(
                    f"Could not find column '{col}' for <dropdown> in GeoDataFrame. "
                )

    # Check for slider (multiple choropleth plots via slider selection):
    if slider is None:
        pass
    elif not isinstance(slider, (list, tuple)):
        raise ValueError(
            "For <slider>, please provide a list/tuple of existing columns of the GeoDataFrame."
        )
    else:
        for col in slider:
            if col not in gdf.columns:
                raise ValueError(
                    f"Could not find column '{col}' for <slider> in GeoDataFrame. "
                )

        if not slider_range is None:
            if not isinstance(slider_range, Iterable):
                raise ValueError(
                    "<slider_range> has to be a type that is iterable like list, tuple, range, ..."
                )
            else:
                slider_range = list(slider_range)
                if len(slider_range) != len(slider):
                    raise ValueError(
                        "The number of elements in <slider_range> has to be the same as in <slider>."
                    )
                steps = []
                for i in range(len(slider_range) - 1):
                    steps.append(slider_range[i + 1] - slider_range[i])

                if len(set(steps)) > 1:
                    raise ValueError(
                        "<slider_range> has to have equal step size between each elements (like a range-object)."
                    )
                else:
                    slider_step = steps[0]
                    slider_start = slider_range[0]
                    slider_end = slider_range[-1]

    # Check colormap if either <category>, <dropdown> or <slider> is choosen:
    if category_options == 1:
        if colormap is None:
            colormap = blue_colormap
        elif isinstance(colormap, (tuple, list)):
            if len(colormap) > 1:
                pass
            else:
                raise ValueError(
                    f"<colormap> only accepts a list/tuple of at least two colors or the name of one of the following predefined colormaps (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): {list(all_palettes.keys())}"
                )
        elif isinstance(colormap, str):
            if colormap in all_palettes:
                colormap = all_palettes[colormap]
                colormap = colormap[max(colormap.keys())]
            else:
                raise ValueError(
                    f"Could not find <colormap> with name {colormap}. The following predefined colormaps are supported (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): {list(all_palettes.keys())}"
                )
        else:
            raise ValueError(
                f"<colormap> only accepts a list/tuple of at least two colors or the name of one of the following predefined colormaps (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): {list(all_palettes.keys())}"
            )
    else:
        if isinstance(color, str):
            colormap = [color]
        elif color is None:
            colormap = ["blue"]
        else:
            raise ValueError(
                "<color> has to be a string specifying the fill_color of the map glyph."
            )

    # Check xlim & ylim:
    if xlim is not None:
        if isinstance(xlim, (tuple, list)):
            if len(xlim) == 2:
                xmin, xmax = xlim
                for _ in [xmin, xmax]:
                    if not -180 < _ <= 180:
                        raise ValueError(
                            "Limits for x-axis (=Longitude) have to be between -180 and 180."
                        )
                if not xmin < xmax:
                    raise ValueError("xmin has to be smaller than xmax.")

                from pyproj import Transformer

                transformer = Transformer.from_crs("epsg:4326", "epsg:3857")
                xmin = transformer.transform(0, xmin)[0]
                xmax = transformer.transform(0, xmax)[0]
                figure_options["x_range"] = (xmin, xmax)
            else:
                raise ValueError(
                    "Limits for x-axis (=Longitude) have to be of form [xmin, xmax] with values between -180 and 180."
                )
        else:
            raise ValueError(
                "Limits for x-axis (=Longitude) have to be of form [xmin, xmax] with values between -180 and 180."
            )
    if ylim is not None:
        if isinstance(ylim, (tuple, list)):
            if len(ylim) == 2:
                ymin, ymax = ylim
                for _ in [ymin, ymax]:
                    if not -90 < _ <= 90:
                        raise ValueError(
                            "Limits for y-axis (=Latitude) have to be between -90 and 90."
                        )
                if not ymin < ymax:
                    raise ValueError("ymin has to be smaller than ymax.")

                from pyproj import Transformer

                transformer = Transformer.from_crs("epsg:4326", "epsg:3857")
                ymin = transformer.transform(ymin, 0)[1]
                ymax = transformer.transform(ymax, 0)[1]
                figure_options["y_range"] = (ymin, ymax)
            else:
                raise ValueError(
                    "Limits for y-axis (=Latitude) have to be of form [ymin, ymax] with values between -90 and 90."
                )
        else:
            raise ValueError(
                "Limits for y-axis (=Latitude) have to be of form [ymin, ymax] with values between -90 and 90."
            )

    # Create Figure to draw:
    old_layout = None
    if figure is None:
        p = bokeh.plotting.figure(**figure_options)

        # Add Tile Source as Background:
        p = _add_backgroundtile(p, tile_provider, tile_provider_url,
                                tile_attribution, tile_alpha)

    elif isinstance(figure, type(bokeh.plotting.figure())):
        p = figure
    elif isinstance(figure, type(column())):
        old_layout = figure
        p = _get_figure(old_layout)
    else:
        raise ValueError(
            "Parameter <figure> has to be of type bokeh.plotting.figure or bokeh.layouts.column."
        )

    # Get ridd of zoom on axes:
    for t in p.tools:
        if type(t) == WheelZoomTool:
            t.zoom_on_axis = False

    # Hide legend if wanted:
    legend_input = legend
    if isinstance(legend, str):
        pass
    else:
        legend = "GeoLayer"

    # Define colormapper:
    if len(colormap) == 1:
        kwargs["fill_color"] = colormap[0]

    elif not category is None:
        # Check if category column is numerical:
        if not issubclass(gdf[category].dtype.type, np.number):
            raise NotImplementedError(
                f"<category> plot only yet implemented for numerical columns. Column '{category}' is not numerical."
            )

        field = category
        colormapper_options = {"palette": colormap}
        if not colormap_range is None:
            if not isinstance(colormap_range, (tuple, list)):
                raise ValueError(
                    "<colormap_range> can only be 'None' or a tuple/list of form (min, max)."
                )
            elif len(colormap_range) == 2:
                colormapper_options["low"] = colormap_range[0]
                colormapper_options["high"] = colormap_range[1]
        else:
            colormapper_options["low"] = gdf[field].min()
            colormapper_options["high"] = gdf[field].max()
        if colormap_uselog:
            colormapper = LogColorMapper(**colormapper_options)
        else:
            colormapper = LinearColorMapper(**colormapper_options)
        kwargs["fill_color"] = {"field": "Colormap", "transform": colormapper}
        if not isinstance(legend, str):
            legend = str(field)

    elif not dropdown is None:
        # Check if all columns in dropdown selection are numerical:
        for col in dropdown:
            if not issubclass(gdf[col].dtype.type, np.number):
                raise NotImplementedError(
                    f"<dropdown> plot only yet implemented for numerical columns. Column '{col}' is not numerical."
                )

        field = dropdown[0]
        colormapper_options = {"palette": colormap}
        if not colormap_range is None:
            if not isinstance(colormap_range, (tuple, list)):
                raise ValueError(
                    "<colormap_range> can only be 'None' or a tuple/list of form (min, max)."
                )
            elif len(colormap_range) == 2:
                colormapper_options["low"] = colormap_range[0]
                colormapper_options["high"] = colormap_range[1]
        else:
            colormapper_options["low"] = gdf[dropdown].min().min()
            colormapper_options["high"] = gdf[dropdown].max().max()
        if colormap_uselog:
            colormapper = LogColorMapper(**colormapper_options)
        else:
            colormapper = LinearColorMapper(**colormapper_options)
        kwargs["fill_color"] = {"field": "Colormap", "transform": colormapper}
        legend = " " + field

    elif not slider is None:
        # Check if all columns in dropdown selection are numerical:
        for col in slider:
            if not issubclass(gdf[col].dtype.type, np.number):
                raise NotImplementedError(
                    f"<slider> plot only yet implemented for numerical columns. Column '{col}' is not numerical."
                )

        field = slider[0]
        colormapper_options = {"palette": colormap}
        if not colormap_range is None:
            if not isinstance(colormap_range, (tuple, list)):
                raise ValueError(
                    "<colormap_range> can only be 'None' or a tuple/list of form (min, max)."
                )
            elif len(colormap_range) == 2:
                colormapper_options["low"] = colormap_range[0]
                colormapper_options["high"] = colormap_range[1]
        else:
            colormapper_options["low"] = gdf[slider].min().min()
            colormapper_options["high"] = gdf[slider].max().max()
        if colormap_uselog:
            colormapper = LogColorMapper(**colormapper_options)
        else:
            colormapper = LinearColorMapper(**colormapper_options)
        kwargs["fill_color"] = {"field": "Colormap", "transform": colormapper}
        if not isinstance(legend, str):
            legend = "Geolayer"

    # Check that only hovertool_columns or hovertool_string is used:
    if isinstance(hovertool_columns, (list, tuple, str)):
        if len(hovertool_columns) > 0 and hovertool_string is not None:
            raise ValueError(
                "Either <hovertool_columns> or <hovertool_string> can be used, but not both at the same time."
            )
    else:
        raise ValueError(
            "<hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'."
        )

    if hovertool_string is not None:
        hovertool_columns = "all"

    # Check for Hovertool columns:
    if hovertool:
        if not isinstance(hovertool_columns, (list, tuple)):
            if hovertool_columns == "all":
                hovertool_columns = list(
                    filter(lambda col: col != geometry_column, gdf.columns))
            else:
                raise ValueError(
                    "<hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'."
                )
        elif len(hovertool_columns) == 0:
            if not category is None:
                hovertool_columns = [category]
            elif not dropdown is None:
                hovertool_columns = dropdown
            elif not slider is None:
                hovertool_columns = slider
            else:
                hovertool_columns = []
        else:
            for col in hovertool_columns:
                if col not in gdf.columns:
                    raise ValueError(
                        f"Could not find columns '{col}' in GeoDataFrame. <hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'."
                    )
    else:
        if category is None:
            hovertool_columns = []
        else:
            hovertool_columns = [category]

    # Reduce DataFrame to needed columns:
    if type(gdf) == pd.DataFrame:
        gdf["Geometry"] = 0
        additional_columns = ["x", "y"]
    else:
        additional_columns = [geometry_column]
    for kwarg, value in kwargs.items():
        if isinstance(value, Hashable):
            if value in gdf.columns:
                additional_columns.append(value)
    if category_options == 0:
        gdf = gdf[list(set(hovertool_columns) | set(additional_columns))]
    else:
        gdf = gdf[list(
            set(hovertool_columns) | set(category_columns)
            | set(additional_columns))]
        gdf["Colormap"] = gdf[field]
        field = "Colormap"

    # Create GeoJSON DataSource for Plot:
    if type(gdf) != pd.DataFrame:
        geo_source = GeoJSONDataSource(geojson=gdf.to_json())
    else:
        geo_source = gdf

    # Draw Glyph on Figure:
    layout = None
    if "Point" in layertypes:
        if "line_color" not in kwargs:
            kwargs["line_color"] = kwargs["fill_color"]
        glyph = p.scatter(x="x",
                          y="y",
                          source=geo_source,
                          legend_label=legend,
                          **kwargs)

    if "Line" in layertypes:
        if "line_color" not in kwargs:
            kwargs["line_color"] = kwargs["fill_color"]
            del kwargs["fill_color"]
        glyph = p.multi_line(xs="xs",
                             ys="ys",
                             source=geo_source,
                             legend_label=legend,
                             **kwargs)

    if "Polygon" in layertypes:

        if "line_color" not in kwargs:
            kwargs["line_color"] = "black"

        # Creates from a geoDataFrame with Polygons and Multipolygons a Pandas DataFrame
        # with x any y columns specifying the geometry of the Polygons:
        geo_source = ColumnDataSource(
            convert_geoDataFrame_to_patches(gdf, geometry_column))

        # Plot polygons:
        glyph = p.multi_polygons(xs="__x__",
                                 ys="__y__",
                                 source=geo_source,
                                 legend_label=legend,
                                 **kwargs)

    # Add hovertool:
    if hovertool and (category_options == 1 or len(hovertool_columns) > 0):
        my_hover = HoverTool(renderers=[glyph])
        if hovertool_string is None:
            my_hover.tooltips = [(str(col), "@{%s}" % col)
                                 for col in hovertool_columns]
        else:
            my_hover.tooltips = hovertool_string
        p.add_tools(my_hover)

    # Add colorbar:
    if show_colorbar and category_options == 1:
        colorbar_options = {
            "color_mapper": colormapper,
            "label_standoff": 12,
            "border_line_color": None,
            "location": (0, 0),
        }
        if colormap_uselog:
            colorbar_options["ticker"] = LogTicker()

        if colorbar_tick_format:
            colorbar_options["formatter"] = get_tick_formatter(
                colorbar_tick_format)

        colorbar = ColorBar(**colorbar_options)

        p.add_layout(colorbar, "right")

    # Add Dropdown Widget:
    if not dropdown is None:
        # Define Dropdown widget:
        dropdown_widget = Select(title="Select Choropleth Layer",
                                 options=list(zip(dropdown, dropdown)))

        # Define Callback for Dropdown widget:
        callback = CustomJS(
            args=dict(
                dropdown_widget=dropdown_widget,
                geo_source=geo_source,
                legend=p.legend[0].items[0],
            ),
            code="""

                //Change selection of field for Colormapper for choropleth plot:
                geo_source.data["Colormap"] = geo_source.data[dropdown_widget.value];
                geo_source.change.emit();

                //Change label of Legend:
                legend.label["value"] = " " + dropdown_widget.value;

                            """,
        )
        dropdown_widget.js_on_change("value", callback)

        # Add Dropdown widget above the plot:
        if old_layout is None:
            layout = column(dropdown_widget, p)
        else:
            layout = column(dropdown_widget, old_layout)

    # Add Slider Widget:
    if not slider is None:

        if slider_range is None:
            slider_start = 0
            slider_end = len(slider) - 1
            slider_step = 1

        value2name = ColumnDataSource({
            "Values":
            np.arange(slider_start, slider_end + slider_step, slider_step),
            "Names":
            slider,
        })

        # Define Slider widget:
        slider_widget = Slider(
            start=slider_start,
            end=slider_end,
            value=slider_start,
            step=slider_step,
            title=slider_name,
        )

        # Define Callback for Slider widget:
        callback = CustomJS(
            args=dict(
                slider_widget=slider_widget,
                geo_source=geo_source,
                value2name=value2name,
            ),
            code="""

                //Change selection of field for Colormapper for choropleth plot:
                var slider_value = slider_widget.value;
                var i;
                for(i=0; i<value2name.data["Names"].length; i++)
                    {
                    if (value2name.data["Values"][i] == slider_value)
                        {
                         var name = value2name.data["Names"][i];
                         }

                    }
                geo_source.data["Colormap"] = geo_source.data[name];
                geo_source.change.emit();

                            """,
        )
        slider_widget.js_on_change("value", callback)

        # Add Slider widget above the plot:
        if old_layout is None:
            layout = column(slider_widget, p)
        else:
            layout = column(slider_widget, old_layout)

    # Hide legend if user wants:
    if legend_input is False:
        p.legend.visible = False

    # Set click policy for legend:
    p.legend.click_policy = "hide"

    # Set panning option:
    if panning is False:
        p.toolbar.active_drag = None

    # Set zooming option:
    if zooming is False:
        p.toolbar.active_scroll = None

    # Display plot and if wanted return plot:
    if layout is None:
        if old_layout is None:
            layout = p
        else:
            layout = old_layout

    # Display plot if wanted
    if show_figure:
        show(layout)

    # Return as (embeddable) HTML if wanted:
    if return_html:
        return embedded_html(layout)

    # Return plot:
    if return_figure:
        return layout
Ejemplo n.º 28
0
def create_satellite_panel(radar_pass, cloudsat_vbl, sat_img_src, sat_src, 
                           traj_df, radar_full_names):
    """Creates bottom panel for the data visualization tool plot."""
    
    # Create color mapper. 
    if cloudsat_vbl == 'radar_refl': 
        color_mapper = LinearColorMapper(palette='Plasma256',low=-2300,high=1500)
    elif cloudsat_vbl == 'cloud_type':
        color_mapper = LinearColorMapper(palette='Paired9',low=-0.5,high=8.5)
    elif cloudsat_vbl == 'cpr_cloud_mask': 
        color_mapper = LinearColorMapper(palette='Paired11',low=-2,high=42)
    elif cloudsat_vbl == 'iwc': 
        cmp = get_hex_matplotlib_cmap('Blues',100,reverse=False)
        cmp.insert(0,'#FFFFFF')
        color_mapper = LinearColorMapper(palette=cmp,low=0,high=0.25)
    elif cloudsat_vbl == 'lwc': 
        cmp = get_hex_matplotlib_cmap('Greens',100,reverse=False)
        cmp.insert(0,'#FFFFFF')
        color_mapper = LinearColorMapper(palette=cmp,low=0,high=1)
    elif cloudsat_vbl == 'iwc_unc': 
        color_mapper = LinearColorMapper(palette='Viridis256',low=0,high=200)
    elif cloudsat_vbl == 'lwc_unc': 
        color_mapper = LinearColorMapper(palette='Viridis256',low=0,high=200)

    # Put the plot together. 
    p2 = figure(title="CloudSat: "+radar_full_names[cloudsat_vbl], toolbar_location="right",
                plot_width=800, plot_height=250, active_scroll = "wheel_zoom",
                x_range=(min(traj_df['t']), max(traj_df['t'])),y_range=(0, 15000))
    sat_im = p2.image('image', source=sat_img_src, x=min(traj_df['t']), 
                      y=radar_pass.cloudsat['height'][0], dw=max(traj_df['t'])-min(traj_df['t']), 
                      dh=(radar_pass.cloudsat['height'][-1]-radar_pass.cloudsat['height'][0]), 
                      color_mapper=color_mapper)
    sat_im.glyph.color_mapper.nan_color = (0, 0, 0, 1)
    lr_sat = p2.line('t','y',source=sat_src,line_color='gray',line_width=3)

    # Add colorbar. 
    #if cloudsat_vbl == 'radar_refl': 
    #    ticker = FixedTicker(ticks=np.linspace(-2300,1500,11))
    #elif cloudsat_vbl == 'cloud_type': 
    #    ticker = FixedTicker(ticks=[i for i in range(9)])
    #elif cloudsat_vbl == 'cpr_cloud_mask':
    #    ticker = FixedTicker(ticks=[4*i for i in range(11)])
    color_bar = ColorBar(color_mapper=color_mapper, bar_line_color='black',
                         major_tick_line_color='black',label_standoff=8, 
                         border_line_color=None, location=(0,0))
    p2.add_layout(color_bar, 'right')

    # Adjust some formatting. 
    p2.xaxis.axis_label = 'Time (UTC)'
    p2.xaxis.axis_label_text_font_size='11pt'
    p2.xaxis.axis_label_text_font_style='normal'
    p2.xaxis.major_label_text_font_size='9pt'
    p2.yaxis.axis_label = 'Height (m)'
    p2.yaxis.axis_label_text_font_size='11pt'
    p2.yaxis.axis_label_text_font_style='normal'
    p2.yaxis.major_label_text_font_size='9pt'

    # Create datetime x axis
    p2.xaxis.formatter = DatetimeTickFormatter(
        hours=["%H:%M:%S"],
        minutes=["%H:%M:%S"],
        seconds=["%H:%M:%S"],
    )

    return p2, sat_src
Ejemplo n.º 29
0
def modify_doc(doc):
    conn = connect_to_db()

    # -------------------------------------------
    # QUERY: TIME SERIES OF H500, ERC AT ONE LOCATION
    # Reading data into a list object 'results' directly from postgres fire_weather_db:
    # cur = conn.cursor()
    # sql =  'select id, lat, lon, date, h500, h500_grad_x, erc from narr_erc \
    #         where lat = 39.2549 and lon = 236.314 \
    #         order by id'
    # df = pd.read_sql(sql, conn)
    # cur.close()
    # conn.close()

    # df.set_index('date', inplace=True)
    # # var = 'h500'
    # # var_title = 'H500'
    # # df_var = df[[var]]
    # # var_list = df_var[var].values.tolist()
    # # var_min = 0.99*(min(var_list))
    # # var_max = 1.01*(max(var_list))

    # dict_from_df = {'date': df.index.values, 'y': df['h500'].values}
    # source = ColumnDataSource(dict_from_df)

    #         p.y_range = DataRange1d(start=var_min, end=var_max)
    #         p.yaxis.axis_label = 'Geopotential gradient, gpm/deg'

    # -------------------------------------------
    # # PLOTTING H500 TIME SERIES
    # p = figure(
    #             x_axis_type = 'datetime',
    #             plot_width = 800,
    #             plot_height = 600,
    #             # y_range = [],
    #             x_axis_label = 'Date',
    #             y_axis_label = 'Geopotential height, gpm',
    #             tools = 'pan,zoom_in,zoom_out,save,reset',
    #             title = 'Time Series'
    #             )

    # p.line(
    #         source = source,
    #         x = 'date',
    #         y = 'y',
    #         line_color = 'green',
    #         line_width = 2
    #         )

    # # THIS SLIDER CAUSES THE DATA TO JUMP BACK TO H500 DATA
    # # EVEN WHEN THE SELECT DROPDOWN SHOWS h500_grad_x. THIS
    # # ISSUE IS NOT RESOLVED. IT'S POSSIBLE THAT BOKEH ISN'T
    # # DESIGNED TO HANDLE CHANGING THE COLUMNS TO BE DISPLAYED
    # # IN ONE PLOT.
    # def slider_callback(attr, old, new):
    #     if new == 0:
    #         data = dict_from_df
    #     else:
    #         # df = pd.DataFrame(data=source.data)
    #         df = pd.DataFrame(dict_from_df)
    #         df.set_index('date', inplace=True)

    #         data = df.rolling(new).mean() #'{0}D'.format(new)).mean()

    #     source.data = ColumnDataSource(data=data).data

    # def select_callback(attr, old, new):
    #     if new == 'h500':
    #         # data = df[[new]]
    #         source.data = {'date': df.index.values, 'y': df['h500'].values}
    #         # Rebuilding dict_from_df to pass to slider_callback():
    #         dict_from_df = {'date': df.index.values, 'y': df['h500'].values}

    #     elif new == 'h500_grad_x':
    #         # data = df[[new]]
    #         source.data = {'date': df.index.values, 'y': df['h500_grad_x'].values}

    #         # Rebuilding dict_from_df to pass to slider_callback():
    #         dict_from_df = {'date': df.index.values, 'y': df['h500_grad_x'].values}

    #         # Figure p data:
    #         var_list = df['h500_grad_x'].values.tolist()
    #         var_min = 0.99*(min(var_list))
    #         var_max = 1.01*(max(var_list))

    #         p.y_range = DataRange1d(start=var_min, end=var_max)
    #         p.yaxis.axis_label = 'Geopotential gradient, gpm/deg'

    #     dict_from_df = source.data

    # # Widgets
    # slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
    # slider.on_change('value', slider_callback)
    # select = Select(title="Weather Variable:", value="h500", options=["h500","h500_grad_x"])#["H500", "H500 X Gradient", "H500 Y Gradient", "PMSL", "PMSL X Gradient", "PMSL Y Gradient", "Energy Release Component"])
    # select.on_change('value', select_callback)

    # # Layout
    # # widget_layout = widgetbox(slider, select)
    # # layout = row(slider, p)

    # # Add root:
    # doc.add_root(row(column(slider,select), p))
    # # doc.add_root(row(slider, p))
    # # doc.add_root(row(select, p))

    # # doc.add_root(widget_layout, p)

    # # curdoc().add_root(widget_layout)

    # doc.theme = Theme(filename="fwp_theme.yaml")

    # -------------------------------------------
    # # PLOTTING ERC TIME SERIES
    # p = figure(
    #         x_axis_type = 'datetime',
    #         plot_width = 800,
    #         plot_height = 600,
    #         # y_range = h500_list,
    #         title = 'ERC Time Series',
    #         x_axis_label = 'Date',
    #         y_axis_label = 'ERC, AU',
    #         tools = 'pan,zoom_in,zoom_out,save,reset',
    #         )

    # p.line(
    #         source = source,
    #         x = 'date',
    #         y = 'erc',
    #         line_color = 'red',
    #         legend = 'ERC',
    #         line_width=2
    #         )
    # -------------------------------------------
    # SQL QUERY: H500 CONTOUR SINGLE DATE
    # Reading data into a list object 'results' directly from postgres database fire_weather_db:
    cur = conn.cursor()

    # Selecting a specific day:
    # sql =  "select id, lat, lon, date, h500, h500_grad_x, pmsl, pmsl_grad_x, pmsl_grad_y, erc from narr_erc \
    #         where cast(date as date) = '1979-05-15' \
    #         order by id"

    # Selecting all days:
    sql = "select id, lat, lon, date, h500, h500_grad_x, erc from narr_erc \
            where cast(date as date) >= '1979-01-02' \
            order by id"

    df = pd.read_sql(sql, conn)
    cur.close()
    conn.close()
    # -------------------------------------------
    # # PLOTTING NARR GRID
    # x = df['lon']
    # y = df['lat']

    # p = figure(
    #       plot_width = 800,
    #       plot_height = 600,
    #         title = 'NARR Grid',
    #         x_axis_label = 'Lon',
    #         y_axis_label = 'Lat',
    #         tools = 'pan,zoom_in,zoom_out,save,reset',
    #         )

    # p.circle(x, y, size=2, color="black", alpha=0.5)
    # -------------------------------------------
    # PLOTTING H500 CONTOUR
    var = 'h500'  # e.g. 'h500', 'h500_grad_x', 'erc'
    var_title = 'H500'  # e.g. 'H500', 'H500 - X Gradient', 'ERC'

    # Creating mesh of lon and lat then using it to create a mesh of
    # the plotting data (the z data needs to be in meshgrid format,
    # the lat lon data does not):
    lon = df['lon'].drop_duplicates('first').to_numpy()
    lat = df['lat'].drop_duplicates('first').to_numpy()
    lonlon, latlat = np.meshgrid(lon, lat)
    mesh_shape = np.shape(lonlon)

    # If var = 'erc', change -32767 to 0:
    if var == 'erc':
        criteria = df[df['erc'] == -32767].index
        df['erc'].loc[criteria] = 0

    # Getting selected day
    df.set_index('date', inplace=True)
    date_list = df.index.unique().tolist()  # df['date'].unique().tolist()
    date_select = date_list[0]
    df = df[[var]]
    df_one_day = df.loc[date_select]  #[var]
    d = df_one_day.to_numpy().reshape(mesh_shape)

    # source = ColumnDataSource(df)

    print('Unique date list:\n', date_list)
    print('Selected date:\n', date_select)
    print('df_one_day:\n', df_one_day)
    print('d on a selected day:\n', d)

    # Min and max synoptic variable values:
    # GETS VALUES ONLY FOR ONE DAY OF YEAR:
    var_list = df_one_day[var].values.tolist()
    # GETS VALUES FOR ENTIRE YEAR:
    # var_list = df[var].values.tolist()
    # print('var_list:\n', var_list)
    var_min = min(var_list)
    var_max = max(var_list)
    print('var_min:\n', var_min)

    # Min and max lingitude and latitude for x_range and y_range:
    lon_min = np.min(lon)
    lon_max = np.max(lon)
    dw = lon_max - lon_min
    lat_min = np.min(lat)
    lat_max = np.max(lat)
    dh = lat_max - lat_min
    print('lat_min:\n', lat_min)

    p = figure(
        #toolbar_location="left",
        title=var_title,
        plot_width=580,
        plot_height=600,
        tooltips=[("lon", "$lon"), ("lat", "$lat"), ("value", "@image")],
        x_range=(lon_min, lon_max),
        y_range=(lat_min, lat_max),
        x_axis_label='Longitude, deg',
        y_axis_label='Latitude, deg')

    # Set palette depending on variable to be plotted
    if var == 'h500_grad_x' or 'h500_grad_y' or 'pmsl_grad_x' or 'pmsl_grad_y':
        # Color maps that make 0 values clear:
        # color_mapper = LinearColorMapper(palette=cividis(256), low=var_min, high=var_max)
        color_mapper = LinearColorMapper(palette="Inferno256",
                                         low=var_min,
                                         high=var_max)
    else:
        color_mapper = LinearColorMapper(palette="Inferno256",
                                         low=var_min,
                                         high=var_max)
        # Decent color map: "Spectra11", "Viridis256"

    # Giving a vector of image data for image parameter (contour plot)
    # p.image(image=[d], x=lon_min, y=lat_min, dw=dw, dh=dh, color_mapper=color_mapper)
    source = ColumnDataSource({'image': [d]})
    p.image(image='image',
            x=lon_min,
            y=lat_min,
            dw=dw,
            dh=dh,
            color_mapper=color_mapper,
            source=source)

    # p.x_range.range_padding = p.y_range.range_padding = 0

    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=BasicTicker(),
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))

    p.add_layout(color_bar, 'right')

    # Get state boundaries from state map data imported from Bokeh
    state_lats = [states[code]["lats"] for code in states]
    state_lons = [states[code]["lons"] for code in states]
    # add 360 to adjust lons to NARR grid
    state_lons = np.array([np.array(sublist) for sublist in state_lons])
    state_lons += 360

    # Patch the state and coastal boundaries
    p.patches(state_lons,
              state_lats,
              fill_alpha=0.0,
              line_color="black",
              line_width=2,
              line_alpha=0.3)

    # select = Select(title="Weather Variable:", value="H500", options=["H500", "H500 X Gradient", "H500 Y Gradient", "PMSL", "PMSL X Gradient", "PMSL Y Gradient", "Energy Release Component"])
    # slider = Slider(start=DateTime(1979,1,2), end=DateTime(1979,12,31), value=DateTime(1979,1,2), step=1, title="Date")
    # slider = Slider(start=1, end=365, step=10, title="Date")

    # def callback(attr, old, new):
    #   points = slider.value
    #   data_points.data = {'x': random(points), 'y': random(points)}

    # To run on bokeh server:
    # bokeh serve --show fwp_app.py

    # # Limit the view to the min and max of the building data
    # p.x_range = DataRange1d(lon_min, lon_max)
    # p.y_range = DataRange1d(lat_min, lat_max)
    # p.xaxis.visible = False
    # p.yaxis.visible = False
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None

    # show(p)

    # output_file("image.html", title="image.py example")

    # show(p)  # open a browser

    # script, div = components(p)

    # The data below is passed to add_user_fwp.html to run when localhost:5000/ is opened.
    # return render_template('add_user_fwp.html', narr_erc_all=narr_erc_all, narr_erc_lat=narr_erc_lat, narr_erc_date=narr_erc_date, script=script, div=div)
    # return render_template('fwp_bokeh_render.html', script=script, div=div, widget_layout=widget_layout)
    # return render_template('bokeh_practice.html', results=results)

    def slider_callback(attr, old, new):
        # if new == 0:
        #     date_select = date_list[0]
        #     print('date_select in callback:\n', date_select)
        #     df_one_day = df.loc[date_select] #[var]
        #     print('df_one_day in callback:\n', df_one_day)
        #     d = df_one_day.to_numpy().reshape(mesh_shape)
        #     print('d in callback:\n', d)

        # else:
        #     date_select = date_list[new]
        #     print('date_select in callback:\n', date_select)
        #     df_one_day = df.loc[date_select] #[var]
        #     print('df_one_day in callback:\n', df_one_day)
        #     d = df_one_day.to_numpy().reshape(mesh_shape)
        #     print('d in callback:\n', d)

        # df = pd.DataFrame(data=source.data)
        # df = pd.DataFrame(dict_from_df)
        # df.set_index('date', inplace=True)
        # data = df.rolling(new).mean() #'{0}D'.format(new)).mean()
        date_select = date_list[slider.value]
        print('date_select in callback:\n', date_select)
        df_one_day = df.loc[date_select]  #[var]
        print('df_one_day in callback:\n', df_one_day)
        d = df_one_day.to_numpy().reshape(mesh_shape)
        print('d in callback:\n', d)
        # source.data = ColumnDataSource(data=data).data

        source.data = {'image': [d]}

        # ---------------------------------
        # THIS WORKS. UNCOMMENT TO USE:
        # Adjusting color mapper one each slider change:
        var_list = df_one_day[var].values.tolist()
        var_min = min(var_list)
        var_max = max(var_list)
        # color_mapper = LinearColorMapper(palette=cividis(256), low=var_min, high=var_max)
        cm = p.select_one(LinearColorMapper)
        cm.update(low=var_min, high=var_max)
        # ---------------------------------

    slider = Slider(start=0, end=364, value=0, step=1, title="Day of Year")
    # slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
    slider.on_change('value', slider_callback)

    # def select_callback(attr, old, new):
    #     if new == 'h500':
    #         # data = df[[new]]
    #         source.data = {'date': df.index.values, 'y': df['h500'].values}
    #         # Rebuilding dict_from_df to pass to slider_callback():
    #         dict_from_df = {'date': df.index.values, 'y': df['h500'].values}

    #     elif new == 'h500_grad_x':
    #         # data = df[[new]]
    #         source.data = {'date': df.index.values, 'y': df['h500_grad_x'].values}

    #         # Rebuilding dict_from_df to pass to slider_callback():
    #         dict_from_df = {'date': df.index.values, 'y': df['h500_grad_x'].values}

    #         # Figure p data:
    #         var_list = df['h500_grad_x'].values.tolist()
    #         var_min = 0.99*(min(var_list))
    #         var_max = 1.01*(max(var_list))

    #         p.y_range = DataRange1d(start=var_min, end=var_max)
    #         p.yaxis.axis_label = 'Geopotential gradient, gpm/deg'

    #     dict_from_df = source.data

    # # Widgets
    # slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
    # slider.on_change('value', slider_callback)
    # select = Select(title="Weather Variable:", value="h500", options=["h500","h500_grad_x"])#["H500", "H500 X Gradient", "H500 Y Gradient", "PMSL", "PMSL X Gradient", "PMSL Y Gradient", "Energy Release Component"])
    # select.on_change('value', select_callback)

    # # Layout
    # widget_layout = widgetbox(slider, select)
    # layout = row(slider, p)

    # # Add root:
    # doc.add_root(row(column(slider,select), p))
    doc.add_root(row(slider, p))
    # doc.add_root(row(select, p))
    # doc.add_root(widget_layout, p)

    # curdoc().add_root(widget_layout)

    doc.theme = Theme(filename="fwp_theme.yaml")
Ejemplo n.º 30
0
#Input GeoJSON source that contains features for plotting.
geosource = GeoJSONDataSource(geojson = json_data(2016))
#Define a sequential multi-hue color palette.
# palette = brewer['YlOrRd'][9]
palette = all_palettes['PuOr'][10]
#Reverse color order so that dark blue is highest obesity.
palette = palette[::-1]
#Instantiate LinearColorMapper that linearly maps numbers in a range, into a sequence of colors. Input nan_color.
color_mapper = LinearColorMapper(palette = palette, low = 0, high = 100, nan_color = '#A9A9A9')
#Define custom tick labels for color bar.
tick_labels = {'0': '0%', '10': '10%', '20':'20%', '30' : '30%', '40':'40%', '50':'50%', '60':'60%', '70':'70%','80':'80%', '90': '90%', '100': '100%'}
#Add hover tool
hover = HoverTool(tooltips = [ ('Country/region','@country'),('% internet usage', '@percent_usage_of_internet')])
#Create color bar. 
color_bar = ColorBar(color_mapper=color_mapper, label_standoff=8,width = 500, height = 20,
                     border_line_color=None,location = (0,0), orientation = 'horizontal', major_label_overrides = tick_labels)
#Create figure object.
p = figure(title = 'Share of individuals with Internet access, 2016', plot_height = 600 , plot_width = 950, toolbar_location = None, tools = [hover])
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
#Add patch renderer to figure. 
p.patches('xs','ys', source = geosource,fill_color = {'field' :'percent_usage_of_internet', 'transform' : color_mapper},
          line_color = 'black', line_width = 0.25, fill_alpha = 1)
#Specify layout
p.add_layout(color_bar, 'below')

# Make a slider object: slider 
slider = Slider(title = 'Year',start = 1990, end = 2016, step = 1, value = 2016)
slider.on_change('value', update_plot)

# Make a column layout of widgetbox(slider) and plot, and add it to the current document