Example #1
0
    def _addlegend(self):
        # Add the color bar
        if 'z_axis_type' in pytplot.data_quants[self.tvar_name].zaxis_opt:
            if pytplot.data_quants[self.tvar_name].zaxis_opt['z_axis_type'] == 'log':
                color_mapper = LogColorMapper(palette=self.colors[0], low=self.zmin, high=self.zmax)
                color_bar = ColorBarSideTitle(color_mapper=color_mapper, ticker=LogTicker(), border_line_color=None,
                                              location=(0, 0))
                color_bar.formatter = BasicTickFormatter(precision=2)
            else:
                color_mapper = LinearColorMapper(palette=self.colors[0], low=self.zmin, high=self.zmax)
                color_bar = ColorBarSideTitle(color_mapper=color_mapper, ticker=BasicTicker(), border_line_color=None,
                                              location=(0, 0))
                color_bar.formatter = BasicTickFormatter(precision=4)
        else:
            color_mapper = LogColorMapper(palette=self.colors[0], low=self.zmin, high=self.zmax)
            color_bar = ColorBarSideTitle(color_mapper=color_mapper, ticker=LogTicker(), border_line_color=None,
                                          location=(0, 0))
            color_bar.formatter = BasicTickFormatter(precision=2)
        color_bar.width = 10
        color_bar.major_label_text_align = 'left'
        color_bar.label_standoff = 5
        color_bar.major_label_text_baseline = 'middle'
        
        color_bar.title = pytplot.data_quants[self.tvar_name].zaxis_opt['axis_label']
        color_bar.title_text_font_size = str(pytplot.data_quants[self.tvar_name].extras['char_size'])+'pt'
        color_bar.title_text_font_style = 'bold'
        color_bar.title_standoff = 20

        self.fig.add_layout(color_bar, 'right')
Example #2
0
def build_plot(tweet_feature):

    tweet_source = ColumnDataSource(data=dict(x=tweet_feature['x'],
                                    y=tweet_feature['y'],
                                    text=tweet_feature['text'],
                                    url=tweet_feature['url'],
                                    color=tweet_feature['color']))

    p = figure(plot_width=600, plot_height=600,
               tools=[HoverTool(tooltips="""<div style="width:300px">@text</div>"""),
                       TapTool()],
               toolbar_location=None,
               title='hover to view tweet text, click to view tweet in a pop-up window')
    tap = p.select(type=TapTool)
    tap.callback = OpenURL(url='@url')
    p.axis.visible = False
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None

    color_mapper=LogColorMapper(palette='Viridis256',
                                low=1, high=max(tweet_feature['popularity'])+1)
    color_bar=ColorBar(color_mapper=color_mapper, ticker=LogTicker(),
                       label_standoff=6, border_line_color=None, location=(0,0),
                       title="likes")

    p.circle(x='x', y='y', source=tweet_source, size=8,
              fill_color='color', line_color='color')
    p.add_layout(color_bar, 'right')
    
    return components(p)
Example #3
0
 def test_custom_colorbar_ticker(self):
     ticker = LogTicker()
     img = Image(np.array([[0, 1],
                           [2,
                            3]])).options(colorbar=True,
                                          colorbar_opts=dict(ticker=ticker))
     plot = bokeh_renderer.get_plot(img)
     colorbar = plot.handles['colorbar']
     self.assertIs(colorbar.ticker, ticker)
def create_vertical_color_bar_with_log_cmap(height='auto', width='auto'):
    color_mapper = LogColorMapper(low=1, high=100000, palette='Viridis256')
    color_bar = ColorBar(orientation='vertical',
                         color_mapper=color_mapper,
                         height=height,
                         width=width,
                         ticker=LogTicker(),
                         label_standoff=12)
    return color_bar
Example #5
0
def plot(location, predictions, state_name):
    from bokeh.sampledata.us_counties import data as counties
    #print(counties.keys())
    counties = {
        code: county
        for code, county in counties.items()
        if county["state"] in [state_name]
    }
    print(len(counties))
    #print(type(counties))
    county_xs = [county["lons"] for county in counties.values()]
    county_ys = [county["lats"] for county in counties.values()]
    county_names = [county['name'] for county in counties.values()
                    ]  #Make sure names match with data
    print(county_names)
    color_mapper = LinearColorMapper(palette=palette, low=25, high=75)
    data = dict(
        x=county_xs,
        y=county_ys,
        name=county_names,
        rate=predictions,
    )
    TOOLS = "pan,wheel_zoom,reset,hover,save"

    p = figure(title="Vote Preference Predictions",
               tools=TOOLS,
               plot_width=900,
               x_axis_location=None,
               y_axis_location=None,
               tooltips=[("Name", "@name"), ("Yes vote (percent)", "@rate%")])

    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=LogTicker(),
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))
    p.add_layout(color_bar, 'right')

    p.grid.grid_line_color = None
    p.hover.point_policy = "follow_mouse"

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

    script, div = components(p)
    return script, div
Example #6
0
def update_colorbar(selectedAgegroups, selectedMeasure):
    df_selected = df.loc[:, (
        df.columns.isin(['AGEGROUP', 'Time', selectedMeasure, 'NAME']))]
    df_selected = df_selected[df_selected.AGEGROUP.isin(
        selectedAgegroups)].copy()
    df_selected = df_selected.groupby(['Time', 'NAME'], sort=False).sum()
    a, b = df_selected.iloc[:, 0].min(), df_selected.iloc[:, 0].max()

    # If total below 250, use linear colormapper
    if (b - a < 250):
        try:
            if (b - a < 8):
                color_bar.color_mapper = LinearColorMapper(palette=palette,
                                                           low=a,
                                                           high=a + 8,
                                                           nan_color='#d9d9d9')
                color_bar.ticker = BasicTicker(desired_num_ticks=8)
            else:
                color_bar.color_mapper = LinearColorMapper(palette=palette,
                                                           low=a,
                                                           high=b,
                                                           nan_color='#d9d9d9')
                color_bar.ticker = BasicTicker(desired_num_ticks=8)
        except:
            color_bar.color_mapper = LinearColorMapper(palette=palette,
                                                       low=0,
                                                       high=8,
                                                       nan_color='#d9d9d9')
            color_bar.ticker = BasicTicker(desired_num_ticks=8)

    else:
        try:
            color_bar.color_mapper = LogColorMapper(palette=palette,
                                                    low=a + 1,
                                                    high=b,
                                                    nan_color='#d9d9d9')
            color_bar.ticker = LogTicker(desired_num_ticks=8)
        except:
            color_bar.color_mapper = LinearColorMapper(palette=palette,
                                                       low=0,
                                                       high=8,
                                                       nan_color='#d9d9d9')
            color_bar.ticker = BasicTicker(desired_num_ticks=8)

    # Adjust the colors used in the map accordingly
    duh.glyph.fill_color = {
        'field': 'Infected_plus',
        'transform': color_bar.color_mapper
    }
        def scale_radiobuttongroup_callback(selection):
            if selection == 0:  # Linear
                for image_view in image_views:
                    image_view.image_glyph.color_mapper = lin_colormapper
                color_bar.color_mapper = lin_colormapper
                color_bar.ticker = BasicTicker()

            else:  # Logarithmic
                if self.disp_min > 0:
                    for image_view in image_views:
                        image_view.image_glyph.color_mapper = log_colormapper
                    color_bar.color_mapper = log_colormapper
                    color_bar.ticker = LogTicker()
                else:
                    scale_radiobuttongroup.active = 0
Example #8
0
    def createFigure(self, event, zside, subdet, layer):
        layer_range = range(1, 29, 2)
        # if subdet == 3:
        #     layer_range = range(1,29)
        #
        range_x = None
        range_y = None
        for layer in layer_range:
            index = (event, zside, subdet, layer)
            title = 'Event: {}, SubDet: {}, zside: {}, layer: {}'.format(
                event, subdet, zside, layer)
            TOOLS = "pan,wheel_zoom,reset,box_zoom,hover,save"
            if range_x is None:
                self.figures[index] = figure(title=title,
                                             tools=TOOLS,
                                             toolbar_location='right',
                                             x_axis_location='below',
                                             y_axis_location='left',
                                             x_range=[-170, +170],
                                             y_range=[-170, 170])
                range_x = self.figures[index].x_range
                range_y = self.figures[index].y_range
            else:
                self.figures[index] = figure(title=title,
                                             tools=TOOLS,
                                             toolbar_location='right',
                                             x_axis_location='below',
                                             y_axis_location='left',
                                             x_range=range_x,
                                             y_range=range_y)
            self.figures[index].grid.grid_line_color = None
            color_bar = ColorBar(color_mapper=self.color_mapper,
                                 ticker=LogTicker(),
                                 label_standoff=12,
                                 border_line_color=None,
                                 location=(0, 0))
            self.figures[index].add_layout(color_bar, 'right')

            hover = self.figures[index].select_one(HoverTool)
            hover.point_policy = "follow_mouse"
            hover.tooltips = [
                ("ID", "@id"),
                #("X", "@x"),
                ("energy", "@energy GeV"),
                ("(x, y)", "($x, $y)"),
                #("CL ID", "@cl_id")
            ]
Example #9
0
    def _draw_colorbar(self, plot, color_mapper):
        if CategoricalColorMapper and isinstance(color_mapper, CategoricalColorMapper):
            return
        if LogColorMapper and isinstance(color_mapper, LogColorMapper):
            ticker = LogTicker()
        else:
            ticker = BasicTicker()
        cbar_opts = dict(self.colorbar_specs[self.colorbar_position])

        # Check if there is a colorbar in the same position
        pos = cbar_opts['pos']
        if any(isinstance(model, ColorBar) for model in getattr(plot, pos, [])):
            return

        opts = dict(cbar_opts['opts'], **self._colorbar_defaults)
        color_bar = ColorBar(color_mapper=color_mapper, ticker=ticker,
                             **dict(opts, **self.colorbar_opts))

        plot.add_layout(color_bar, pos)
        self.handles['colorbar'] = color_bar
Example #10
0
 def make_plot(src):
     p = figure(
         plot_width=print_width,
         plot_height=print_height,
         x_range=(0, 1900),
         y_range=(
             1200,
             0),  #y value is manipulated to have the correct coordinates.
         #in the dataset origin is treated to be the upper left corner. While graphing it is lower left.
         #Therefore we "flip" the y axis in the dataset.
         title='Heatmap',
         x_axis_label='x coordinate',
         y_axis_label='y coordinate')
     image = ImageURL(url="url", x=0, y=0, w='w', h='h')
     #p.image_url(url = ["https://www.jelter.net/stimuli/" + selectStation.value],
     #            x = 0 , y = 0, w = width, h = height) #'../../' +
     p.add_glyph(src, image)
     colors = [
         "#0000FF", "#0072FF", "#00FF00", "#D1FF00", "#FFC500", "#FF6C00",
         "#FF0000"
     ]
     cmap = LinearColorMapper(palette=colors)
     p.ellipse(x="x",
               y="y",
               source=src,
               line_color=None,
               fill_color=transform('closeness', cmap),
               width=dia,
               height=dia,
               alpha=alp)
     color_bar = ColorBar(color_mapper=cmap,
                          ticker=LogTicker(),
                          label_standoff=12,
                          border_line_color=None,
                          location=(0, 0))
     p.add_layout(color_bar, 'right')
     return p
Example #11
0
                          errors='coerce'))
    else:
        dictionary['Country'] = data['Country'].astype(str)

source = ColumnDataSource(data=dictionary)

menu = []
for key in data.keys():
    if key != "Country":
        menu.append((key, key))

color_mapper = LogColorMapper(palette="Turbo256",
                              low=min(dictionary['Birth rate']),
                              high=max(dictionary['Birth rate']))
color_bar1 = ColorBar(color_mapper=color_mapper,
                      ticker=LogTicker(),
                      label_standoff=12,
                      border_line_color=None,
                      location=(0, 0))
color_bar2 = ColorBar(color_mapper=color_mapper,
                      ticker=LogTicker(),
                      label_standoff=12,
                      border_line_color=None,
                      location=(0, 0))
color_bar3 = ColorBar(color_mapper=color_mapper,
                      ticker=LogTicker(),
                      label_standoff=12,
                      border_line_color=None,
                      location=(0, 0))
color_bar4 = ColorBar(color_mapper=color_mapper,
                      ticker=LogTicker(),
Example #12
0
def plot_time_series_spectra(flux,
                             wavelength=None,
                             time=None,
                             xlabel='Column',
                             ylabel='Frame',
                             width=1024,
                             height=300,
                             title=None,
                             **kwargs):
    """
    Plot time series 1D spectra as an image

    Parameters
    ----------
    flux: array-like
        The 2D counts or flux
    wavelength: sequence (optional)
        The 1D wavelength array
    time: sequence (optional)
        The 1D time array
    xlabel: str
        The label for the data x-axis
    ylabel: str
        The label for the data y-axis
    width: int
        The width of the plot
    height: int
        The height of the plot
    title: str
        A title for the plot

    Returns
    -------
    bokeh.plotting.figure.Figure
        The figure
    """
    # Check that flux is 2D
    if not flux.ndim == 2:
        raise ValueError("{}: 'flux' must be a 2D array.".format(flux.shape))

    # Copy flux array
    flx = copy.copy(flux)

    # Get plot params
    dh, dw = flx.shape
    fmin = np.nanmin(flx)
    fmax = np.nanmax(flx)
    wmin, wmax = 0, dw
    tmin, tmax = 0, dh
    lightcurves = flx.T

    # Make sure time array is correct length
    if time is not None:
        if len(time) != dh:
            raise ValueError(
                "{} != {}: 'time' array must be the same length as 'flux' cube."
                .format(len(time), flux.shape[0]))

    # Make sure wavelength array is correct length
    if wavelength is not None:
        if len(wavelength) != dw:
            raise ValueError(
                "{} != {}: 'wavelength' array must be the same depth as 'flux' cube."
                .format(len(wavelength), flux.shape[1]))

    # Major tick labels
    waxis = np.arange(wmin, wmax)
    wstart, wskip = 128, 256
    taxis = np.arange(tmin, tmax)
    tstart, tskip = 1, max(4, min(tmax // 2, 10))

    # Set the source data
    wave_data = np.array(
        [wavelength if wavelength is not None else np.arange(dw)] *
        flx.shape[0])
    time_data = np.array([time if time is not None else np.arange(dh)] *
                         flx.shape[1]).T
    sourceW = ColumnDataSource(
        data=dict(flux=[flx], wavelength=[wave_data], time=[time_data]))
    sourceX = ColumnDataSource(
        data=dict(wavelength=waxis,
                  flux=flx[0],
                  **{'flux{}'.format(n): fx
                     for n, fx in enumerate(flx)}))
    sourceY = ColumnDataSource(data=dict(
        time=taxis,
        lightcurve=lightcurves[0],
        **{'lightcurve{}'.format(n): lc
           for n, lc in enumerate(lightcurves)}))
    sourceZ = ColumnDataSource(data=dict(x=[0.5], y=[0.5]))

    # ====================================================================

    # Make the 2D spectra figure
    spec_fig = figure(x_range=(wmin, wmax),
                      y_range=(tmin, tmax),
                      x_axis_label=xlabel,
                      y_axis_label=ylabel,
                      plot_width=width,
                      plot_height=height,
                      title=title,
                      tools="")

    # Plot the image
    color_mapper = LogColorMapper(palette="Viridis256", low=fmin, high=fmax)
    spec_fig.image(image='flux',
                   x=wmin,
                   y=tmin,
                   dw=wmax,
                   dh=tmax,
                   color_mapper=color_mapper,
                   alpha=0.8,
                   name='img',
                   source=sourceW)
    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=LogTicker(),
                         orientation="horizontal",
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))

    # Add current lightcurve line to plot
    spec_fig.vbar(x='x',
                  width=1,
                  top=tmax,
                  source=sourceZ,
                  color='red',
                  alpha=0.3)

    # Add current spectrum line to plot
    spec_fig.hbar(y='y',
                  height=1,
                  right=wmax,
                  source=sourceZ,
                  color='blue',
                  alpha=0.3)

    # Set the tooltips
    spec_tt = HoverTool(names=["img"],
                        tooltips=[("(x,y)", "($x{int}, $y{int})"),
                                  ("Flux", "@flux"),
                                  ('Wavelength', '@wavelength'),
                                  ('Time', '@time{0.00000}')])
    spec_fig.add_tools(spec_tt)

    # Change y tick labels
    if time is not None:
        spec_fig.yaxis.ticker = taxis[tstart::tskip]
        spec_fig.yaxis.major_label_overrides = {
            int(n): '{:.2f}'.format(t)
            for n, t in zip(taxis[tstart::tskip], time[tstart::tskip])
        }

    # Change x tick labels
    if wavelength is not None:
        spec_fig.xaxis.ticker = waxis[wstart::wskip]
        spec_fig.xaxis.major_label_overrides = {
            int(n): '{:.3f}'.format(w)
            for n, w in zip(waxis[wstart::wskip], wavelength[wstart::wskip])
        }

    # Remove grid lines
    spec_fig.xgrid.grid_line_color = None
    spec_fig.ygrid.grid_line_color = None

    # ====================================================================

    # Make the 1D spectrum figure
    sp_fig = figure(x_range=(wmin, wmax),
                    y_range=(fmin, fmax),
                    width=width,
                    height=height,
                    x_axis_label=xlabel,
                    y_axis_label='Flux Density',
                    title='Spectrum',
                    tools="")

    # Draw the spectrum
    sp_fig.step('wavelength',
                'flux',
                source=sourceX,
                color='blue',
                line_width=3,
                line_alpha=0.6,
                mode='center',
                name='wf')

    # Set the tooltips
    sp_tt = HoverTool(names=['wf'],
                      tooltips=[("Flux", "@flux"),
                                ('Wavelength', '@wavelength')],
                      mode='vline')
    sp_fig.add_tools(sp_tt)

    # Change x tick labels
    if wavelength is not None:
        sp_fig.xaxis.ticker = waxis[wstart::wskip]
        sp_fig.xaxis.major_label_overrides = {
            int(n): '{:.3f}'.format(w)
            for n, w in zip(waxis[wstart::wskip], wavelength[wstart::wskip])
        }

    # Make the spectrum slider
    sp_slider = Slider(value=0,
                       start=tmin,
                       end=tmax - 1,
                       step=1,
                       width=30,
                       title=ylabel,
                       orientation='vertical',
                       direction='rtl',
                       bar_color='blue')

    # ====================================================================

    # Make the 1D lightcurve figure
    lc_fig = figure(x_range=(tmin, tmax),
                    y_range=(fmin, fmax),
                    width=width,
                    height=height,
                    x_axis_label=ylabel,
                    y_axis_label='Flux Density',
                    title='Lightcurve',
                    tools="")

    # Draw the lightcurve
    lc_fig.step('time',
                'lightcurve',
                source=sourceY,
                color='red',
                line_width=3,
                line_alpha=0.6,
                mode='center',
                name='tl')

    # Set the tooltips
    lc_tt = HoverTool(names=['tl'],
                      tooltips=[("Time", "@time"), ('Flux', '@lightcurve')],
                      mode='vline')
    lc_fig.tools.append(lc_tt)

    # Change x tick labels
    if time is not None:
        lc_fig.xaxis.ticker = taxis[tstart::tskip]
        lc_fig.xaxis.major_label_overrides = {
            int(n): '{:.2f}'.format(t)
            for n, t in zip(taxis[tstart::tskip], time[tstart::tskip])
        }

    # Make the lightcurve slider
    lc_slider = Slider(value=0,
                       start=wmin,
                       end=wmax - 1,
                       step=1,
                       width=width,
                       title=xlabel,
                       bar_color='red')

    # ====================================================================

    # CustomJS callback to update the three plots on slider changes
    callback = CustomJS(args=dict(sourcex=sourceX,
                                  sourcey=sourceY,
                                  sourcez=sourceZ,
                                  sp_slide=sp_slider,
                                  lc_slide=lc_slider),
                        code="""
        var datax = sourcex.data;
        var datay = sourcey.data;
        var dataz = sourcez.data;
        var sp = sp_slide.value;
        var lc = lc_slide.value;
        var wavelength = datax['wavelength'];
        var time = datay['time'];
        datax['flux'] = datax['flux'.concat(sp.toString(10))];
        datay['lightcurve'] = datay['lightcurve'.concat(lc.toString(10))];
        dataz['x'] = [lc+0.5];
        dataz['y'] = [sp+0.5];
        sourcex.change.emit();
        sourcey.change.emit();
        sourcez.change.emit();
    """)

    # Add callback to spectrum slider
    sp_slider.js_on_change('value', callback)

    # Add callback to lightcurve slider
    lc_slider.js_on_change('value', callback)

    return gridplot([[sp_fig, None], [spec_fig, sp_slider], [lc_slider, None],
                     [lc_fig, None]])
Example #13
0
def make_map():
    #Create figure object.
    p = figure(title='Map of COVID-19 ' + plot_title[sel_var] + ' (' +
               txt_src + ')',
               plot_height=550,
               plot_width=950,
               x_range=(-180, 180),
               y_range=(-65, 90),
               toolbar_location='above',
               tools='pan, wheel_zoom, box_zoom, reset, tap',
               sizing_mode="scale_width")
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None

    # Choose linear or logarithmic color mapper
    if tog_lin.active:
        mapper = LinearColorMapper(palette=palette,
                                   low=0,
                                   high=plot_max[sel_var])
        ticker = BasicTicker()
    else:
        mapper = LogColorMapper(palette=palette,
                                low=plot_min[sel_var],
                                high=plot_max[sel_var])
        ticker = LogTicker()

    color_bar = ColorBar(color_mapper=mapper,
                         label_standoff=8,
                         height=20,
                         ticker=ticker,
                         border_line_color=None,
                         location=(0, 0),
                         orientation='horizontal')

    if not rb_abs_rel.active:
        color_bar.formatter = NumeralTickFormatter(format='0[.]0a')
    elif not tog_lin.active:
        color_bar.formatter = NumeralTickFormatter(format='0.[00000]')

    #Add patch renderer to figure.
    ren_map = p.patches('xs',
                        'ys',
                        source=source_map,
                        line_color='black',
                        line_width=0.25,
                        fill_color={
                            'field': 'Selected',
                            'transform': mapper
                        },
                        fill_alpha=1)

    #Specify figure layout.
    p.add_layout(color_bar, 'below')

    #Add hover tool
    p.add_tools(
        HoverTool(tooltips=[
            ('Country/region', '@Country'), ('Population', '@Population'),
            ('Tot Cases', '@Cases_Tot_Abs @Cases_Tot_Rel{custom}'),
            ('New Cases', '@Cases_New_Abs @Cases_New_Rel{custom}'),
            ('Avg Cases', '@Cases_Avg_Abs @Cases_Avg_Rel{custom}'),
            ('Tot Deaths', '@Deaths_Tot_Abs @Deaths_Tot_Rel{custom}'),
            ('New Deaths', '@Deaths_New_Abs @Deaths_New_Rel{custom}'),
            ('Avg Deaths', '@Deaths_Avg_Abs @Deaths_Avg_Rel{custom}')
        ],
                  formatters={
                      '@Cases_Tot_Rel': custom,
                      '@Cases_New_Rel': custom,
                      '@Cases_Avg_Rel': custom,
                      '@Deaths_Tot_Rel': custom,
                      '@Deaths_New_Rel': custom,
                      '@Deaths_Avg_Rel': custom
                  }))
    return p
Example #14
0
def outputMapDew(path, mapSelect):

    if mapSelect == 'dew_yield':
        moduleType = 'Sum of Yearly Dew(mmd-1)'
        htmlString = '_yearly_dew'
        colorSelector = "Viridis256"
        #Assign the upper and lower bounds of the map

    #Create the html to be exported
    output_file('Yearly_Dew_Yield_Map(mmd-1)' + htmlString + '.html')

    # Create the tools used for zooming and hovering on the map
    tools = "pan,wheel_zoom,box_zoom,reset,previewsave"

    #Access the .json file to create the map of countries and states
    # THe json files will create layers to overlap the data with
    with open(path + "/Map/countries.geojson", "r") as f:
        countries = bkm.GeoJSONDataSource(geojson=f.read())
    with open(path + "/Map/us-states.json", "r") as f:
        states = bkm.GeoJSONDataSource(geojson=f.read())

    #Access the processed summary data pickle
    level_1_df = pd.read_pickle(
        path + "\\Pandas_Pickle_DataFrames\\Pickle_Map\\Pickle_Map.pickle")

    # Bring in all the data to display on map

    #Radius is the size of the circle to be displayed on the map
    radiusList = []
    for i in range(0, len(level_1_df)):
        #Toggle size of circle
        radiusList.append(2)
    lat = level_1_df['N'].astype(float)  #Northing and easting if Needed
    lon = level_1_df['E'].astype(float)
    radius = radiusList
    dew = level_1_df[moduleType]
    station = level_1_df['Station name']
    latitude = level_1_df['Site latitude']
    longitude = level_1_df['Site longitude']
    moduleTemp = level_1_df[moduleType]
    uniqueID = level_1_df['Site Identifier Code']

    # The Boken map rendering package needs to store data in the ColumnDataFormat
    # Store the lat/lon from the Map_pickle.  Formatting for Lat/Lon has been
    # processed prior see "Map_Pickle_Processing.py" file for more details
    # Add other data to create hover labels
    source = ColumnDataSource(data=dict(Lat=latitude,
                                        Lon=longitude,
                                        radius=radius,
                                        dew=dew,
                                        Station=station,
                                        Latitude=latitude,
                                        Longitude=longitude,
                                        Module_Temp=moduleTemp,
                                        uniqueID=uniqueID))

    p = bkp.figure(width=1500,
                   height=900,
                   tools=tools,
                   title='IWEC, CWEC, and Average Dew Yield(mmd-1)',
                   x_axis_type="mercator",
                   y_axis_type="mercator",
                   x_axis_label='Longitude',
                   y_axis_label='Latitude')

    p.x_range = bkm.Range1d(start=-180, end=180)
    p.y_range = bkm.Range1d(start=-90, end=90)

    #Create the datapoints as overlapping circles
    p.circle(
        "Lon",
        "Lat",
        source=source,
        radius="radius",
        #fill color will use linear_cmap() to scale the colors of the circles being displayed
        fill_color=linear_cmap('dew', colorSelector, low=20, high=300),
        line_color=None,
        # Alpha is the transparency of the circle
        alpha=0.3)
    #Stations will be the black dots displayed on the map
    stations = p.circle(
        "Lon",
        "Lat",
        source=source,
        radius=.1,
        #fill color will use linear_cmap() to scale the colors of the circles being displayed
        fill_color='black',
        line_color=None,
        # Alpha is the transparency of the circle
        alpha=.99)

    #Create the scale bar to the right of the map

    # Create color mapper to make the scale bar on the right of the map
    # palette = color scheme of the mapo
    # low/high sets the scale of the data, use the minimum value and maximum value of the data we are analyzing
    color_mapper = LogColorMapper(palette=colorSelector, low=20, high=300)

    # color bar will be scale bar set to the right of the map
    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=LogTicker(),
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))
    # Assign the scale bar to " p " and put it to the right
    p.add_layout(color_bar, 'right')

    # These are the labels that are displayed when you hover over a spot on the map
    #( label , @data), data needs to be inside the ColumnDataSource()
    TOOLTIPS = [
        ("Station", "@Station"),
        ("Site ID", "@uniqueID"),
        ("Lat", "@Latitude"),
        ("Lon", "@Longitude"),
        ("Yearly_Dew_Yield", "@dew"),
    ]

    #Create a hover tool that will rinder only the weather stations i.e stations are small black circles
    hover_labels = bkm.HoverTool(renderers=[stations], tooltips=TOOLTIPS)
    #Add the hover tool to the map
    p.add_tools(hover_labels)
    #Overlay the Country and States boarders
    p.patches("xs",
              "ys",
              color="white",
              line_color="black",
              source=countries,
              fill_alpha=0,
              line_alpha=1)
    p.patches("xs",
              "ys",
              color="white",
              line_color="black",
              source=states,
              fill_alpha=0,
              line_alpha=1)
    #Display the plot
    show(p)
    def mapGenerator(path, mapSelect, htmlString, title, scaleMin, scaleMax,
                     metric):
        '''
        HELPER FUNCTION
        
        mapGenerator()
        
        Generate a map from the processed level_1_dataframe and diplay as a 
            bokeh map of the earth for each weather station
        
        @param path        - String, of the current working directory                                  
        @param mapSelect   - String, string to select what map to generate
 
         'Annual Global Horizontal Irradiance (GJ/m^-2)',
         'Annual Direct Normal Irradiance (GJ/m^-2)',
         'Annual Diffuse Horizontal Irradiance (GJ/m^-2)',
         'Annual POA Global Irradiance (GJ/m^-2)',
         'Annual POA Direct Irradiance (GJ/m^-2)',
         'Annual POA Diffuse Irradiance (GJ/m^-2)',
         'Annual POA Sky Diffuse Irradiance (GJ/m^-2)',
         'Annual POA Ground Diffuse Irradiance (GJ/m^-2)',
         
         'Annual Global UV Dose (MJ/y^-1)',
         'Annual UV Dose at Latitude Tilt (MJ/y^-1)',
         
         'Annual Minimum Ambient Temperature (C)',
         'Annual Average Ambient Temperature (C)',
         'Annual Maximum Ambient Temperature (C)',
         'Annual Range Ambient Temperature (C)',
         'Average of Yearly Water Vapor Pressure(kPa)',
         'Sum of Yearly Water Vapor Pressure(kPa)',
         "Annual number of Hours Relative Humidity > to 85%",
         'Sum of Yearly Dew(mmd-1)'

        @param htmlString - String, what to name the html 
        @param title      - String, title of the map
        @param scaleMin   - Float,  minimum value of the scale
        @param scaleMax   - Float,  maximum value of the scale        
        @param metric     - String, metric of the value being measured        
        
        @return           -void, Bokeh map as a html
        '''
        colorSelector = "Viridis256"

        #Create the html to be exported
        output_file(htmlString + '.html')

        # Create the tools used for zooming and hovering on the map
        tools = "pan,wheel_zoom,box_zoom,reset,previewsave"

        #Access the .json file to create the map of countries and states
        # The json files will create layers to overlap the data with
        with open(path + "/Map/countries.geojson", "r") as f:
            countries = bkm.GeoJSONDataSource(geojson=f.read())
        with open(path + "/Map/us-states.json", "r") as f:
            states = bkm.GeoJSONDataSource(geojson=f.read())
        #Access the processed summary data pickle
        level_1_df = pd.read_pickle(
            path +
            "\\Pandas_Pickle_DataFrames\\Pickle_Level1_Summary\\Pickle_Level1_Summary.pickle"
        )

        #Radius is the size of the circle to be displayed on the map
        radiusList = []
        for i in range(0, len(level_1_df)):
            #Toggle size of circle
            radiusList.append(2)

        radius = radiusList
        selector = level_1_df[mapSelect]
        station = level_1_df['Station name']
        latitude = level_1_df['Site latitude']
        longitude = level_1_df['Site longitude']
        moduleTemp = level_1_df[mapSelect]
        uniqueID = level_1_df['Site Identifier Code']
        dataSource = level_1_df['Data Source']
        elevation = level_1_df['Site elevation (meters)'].astype(float)

        # The Boken map rendering package needs to store data in the ColumnDataFormat
        # Store the lat/lon from the Map_pickle.  Formatting for Lat/Lon has been
        # processed prior see "Map_Pickle_Processing.py" file for more details
        # Add other data to create hover labels
        source = ColumnDataSource(data=dict(Lat=latitude,
                                            Lon=longitude,
                                            radius=radius,
                                            selector=selector,
                                            Station=station,
                                            Latitude=latitude,
                                            Longitude=longitude,
                                            Module_Temp=moduleTemp,
                                            uniqueID=uniqueID,
                                            elevation=elevation,
                                            dataSource=dataSource))

        p = bkp.figure(width=1500,
                       height=900,
                       tools=tools,
                       title=title,
                       x_axis_type="mercator",
                       y_axis_type="mercator",
                       x_axis_label='Longitude',
                       y_axis_label='Latitude')

        p.x_range = bkm.Range1d(start=-180, end=180)
        p.y_range = bkm.Range1d(start=-90, end=90)

        #Create the datapoints as overlapping circles
        p.circle(
            "Lon",
            "Lat",
            source=source,
            radius="radius",
            #fill color will use linear_cmap() to scale the colors of the circles being displayed
            fill_color=linear_cmap('selector',
                                   colorSelector,
                                   low=scaleMin,
                                   high=scaleMax),
            line_color=None,
            # Alpha is the transparency of the circle
            alpha=0.3)
        #Stations will be the black dots displayed on the map
        stations = p.circle(
            "Lon",
            "Lat",
            source=source,
            radius=.1,
            #fill color will use linear_cmap() to scale the colors of the circles being displayed
            fill_color='black',
            line_color=None,
            # Alpha is the transparency of the circle
            alpha=.99)
        #Create the scale bar to the right of the map
        # Create color mapper to make the scale bar on the right of the map
        # palette = color scheme of the mapo
        # low/high sets the scale of the data, use the minimum value and maximum value of the data we are analyzing
        color_mapper = LinearColorMapper(palette=colorSelector,
                                         low=scaleMin,
                                         high=scaleMax)

        # color bar will be scale bar set to the right of the map
        color_bar = ColorBar(color_mapper=color_mapper,
                             ticker=LogTicker(),
                             label_standoff=12,
                             border_line_color=None,
                             location=(0, 0))
        # Assign the scale bar to " p " and put it to the right
        p.add_layout(color_bar, 'right')
        # These are the labels that are displayed when you hover over a spot on the map
        #( label , @data), data needs to be inside the ColumnDataSource()
        TOOLTIPS = [("Station", "@Station"), ("Site ID", "@uniqueID"),
                    ("Data Source", "@dataSource"), ("Lat", "@Latitude"),
                    ("Lon", "@Longitude"),
                    (htmlString, "@selector" + " " + metric),
                    ("Elevation", "@elevation" + " (m)")]
        #Create a hover tool that will rinder only the weather stations i.e stations are small black circles
        hover_labels = bkm.HoverTool(renderers=[stations], tooltips=TOOLTIPS)
        #Add the hover tool to the map
        p.add_tools(hover_labels)
        #Overlay the Country and States boarders
        p.patches("xs",
                  "ys",
                  color="white",
                  line_color="black",
                  source=countries,
                  fill_alpha=0,
                  line_alpha=1)
        p.patches("xs",
                  "ys",
                  color="white",
                  line_color="black",
                  source=states,
                  fill_alpha=0,
                  line_alpha=1)
        #Display the plot
        show(p)
Example #16
0
def cloud(full_output):
    """
    Plotting the cloud input from ``picaso``. 

    The plot itselfs creates maps of the wavelength dependent single scattering albedo 
    and cloud opacity as a function of altitude. 


    Parameters
    ----------
    full_output

    Returns
    -------
    A row of two bokeh plots with the single scattering and optical depth map
    """
    cols = colfun1(200)
    color_mapper = LinearColorMapper(palette=cols, low=0, high=1)

    dat01 = full_output['layer']['cloud']

    #PLOT W0
    scat01 = np.flip(dat01['w0'], 0)  #[0:10,:]
    xr, yr = scat01.shape
    f01a = figure(x_range=[0, yr],
                  y_range=[0, xr],
                  x_axis_label='Wavelength (micron)',
                  y_axis_label='Pressure (bar)',
                  title="Single Scattering Albedo",
                  plot_width=300,
                  plot_height=300)

    f01a.image(image=[scat01],
               color_mapper=color_mapper,
               x=0,
               y=0,
               dh=xr,
               dw=yr)

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

    f01a.add_layout(color_bar, 'left')

    #PLOT OPD
    scat01 = np.flip(dat01['opd'] + 1e-60, 0)

    xr, yr = scat01.shape
    cols = colfun2(200)[::-1]
    color_mapper = LogColorMapper(palette=cols, low=1e-3, high=10)

    f01 = figure(x_range=[0, yr],
                 y_range=[0, xr],
                 x_axis_label='Wavelength (micron)',
                 y_axis_label='Pressure (bar)',
                 title="Cloud Optical Depth Per Layer",
                 plot_width=300,
                 plot_height=300)

    f01.image(image=[scat01],
              color_mapper=color_mapper,
              x=0,
              y=0,
              dh=xr,
              dw=yr)

    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=LogTicker(),
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))
    f01.add_layout(color_bar, 'left')

    #PLOT G0
    scat01 = np.flip(dat01['g0'] + 1e-60, 0)

    xr, yr = scat01.shape
    cols = colfun3(200)[::-1]
    color_mapper = LinearColorMapper(palette=cols, low=0, high=1)

    f01b = figure(x_range=[0, yr],
                  y_range=[0, xr],
                  x_axis_label='Wavelength (micron)',
                  y_axis_label='Pressure (bar)',
                  title="Assymetry Parameter",
                  plot_width=300,
                  plot_height=300)

    f01b.image(image=[scat01],
               color_mapper=color_mapper,
               x=0,
               y=0,
               dh=xr,
               dw=yr)

    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=BasicTicker(),
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))
    f01b.add_layout(color_bar, 'left')

    #CHANGE X AND Y AXIS TO BE PHYSICAL UNITS
    #indexes for pressure plot
    pressure = [
        "{:.1E}".format(i) for i in full_output['layer']['pressure'][::-1]
    ]  #flip since we are also flipping matrices
    wave = ["{:.2F}".format(i) for i in 1e4 / full_output['wavenumber']]
    nwave = len(wave)
    npres = len(pressure)
    iwave = np.array(range(nwave))
    ipres = np.array(range(npres))
    #set how many we actually want to put on the figure
    #hard code ten on each..
    iwave = iwave[::int(nwave / 10)]
    ipres = ipres[::int(npres / 10)]
    pressure = pressure[::int(npres / 10)]
    wave = wave[::int(nwave / 10)]
    #create dictionary for tick marks
    ptick = {int(i): j for i, j in zip(ipres, pressure)}
    wtick = {int(i): j for i, j in zip(iwave, wave)}
    for i in [f01a, f01, f01b]:
        i.xaxis.ticker = iwave
        i.yaxis.ticker = ipres
        i.xaxis.major_label_overrides = wtick
        i.yaxis.major_label_overrides = ptick

    return row(f01a, f01, f01b)
def create_us_map_tab():
    "Factory for creating second tab of app: US Only Data"

    ## Data Sources
    source_df_confirmed, source_CDS = get_time_series_confirmed_US_data()
    source_CDS.data['number_per_capita'] = source_df_confirmed[
        START_DATE_STRING] / source_df_confirmed['population']

    ## Map
    color_mapper = log_cmap(field_name='number',
                            palette=Spectral6,
                            low=1,
                            high=1e6)

    TOOLTIPS = [('County/Region', '@county'), ('State/Province', '@region'),
                ('Population', '@population'), ('Cases', '@number'),
                ('Cases Per Capita', '@number_per_capita')]

    map_figure = figure(
        title='Confirmed COVID-19 Cases in the United States',
        tooltips=TOOLTIPS,
        x_range=(-18367715, -6901808.43),
        y_range=(0, 13377019.78),
        x_axis_type='mercator',
        y_axis_type='mercator',
        active_scroll='wheel_zoom',
    )

    tile_provider = get_provider(CARTODBPOSITRON)
    map_figure.add_tile(tile_provider)
    map_figure.circle(x='web_mercator_x',
                      y='web_mercator_y',
                      source=source_CDS,
                      size='sizes',
                      color=color_mapper)

    ## Colorbar
    color_bar = ColorBar(title='Num. Cases',
                         title_standoff=20,
                         color_mapper=color_mapper['transform'],
                         label_standoff=20,
                         width=8,
                         location=(0, 0),
                         ticker=LogTicker())
    color_bar.formatter.use_scientific = False
    map_figure.add_layout(color_bar, 'right')

    ## Slider
    def slider_callback(attr, old, new):
        delta = datetime.timedelta(milliseconds=new)
        date = datetime.date(1970, 1, 1) + delta
        date_string = date.strftime('%Y-%m-%d')

        try:
            source_CDS.data['number'] = source_df_confirmed[date_string]
            source_CDS.data['sizes'] = source_df_confirmed[date_string].apply(
                scale)
            source_CDS.data['number_per_capita'] = source_df_confirmed[
                date_string] / source_df_confirmed['population']
        except KeyError:
            pass

    slider = DateSlider(title='Date',
                        start=START_DATE,
                        end=datetime.date.today(),
                        step=1,
                        value=START_DATE)
    slider.on_change('value', slider_callback)

    ## Data Table
    columns = [
        TableColumn(field='county', title='County/Region'),
        TableColumn(field='region', title='State/Province'),
        TableColumn(field='population', title='Population'),
        TableColumn(field='number', title='Cases'),
        TableColumn(field='number_per_capita', title='Cases Per Capita'),
    ]

    data_table = DataTable(
        source=source_CDS,
        columns=columns,
    )

    ## Cancel Selection Button
    def cancel_selection_callback():
        source_CDS.selected.indices = []

    cancel_selection_button = Button(label='Clear Selection',
                                     button_type='warning')
    cancel_selection_button.on_click(cancel_selection_callback)

    child = row([
        column([slider, map_figure]),
        column([data_table, cancel_selection_button])
    ])

    return Panel(child=child, title='United States Map')
Example #18
0
def geoplot(gdf_in,
            fig=None,
            figsize=None,
            title="",
            xlabel="Longitude",
            ylabel="Latitude",
            color="blue",
            colormap=None,
            colormap_uselog=False,
            colormap_range=None,
            category=None,
            dropdown=None,
            slider=None,
            slider_range=None,
            slider_name="",
            show_colorbar=True,
            xrange=None,
            yrange=None,
            hovertool=True,
            hovertool_columns=[],
            simplify_shapes=None,
            tile_provider="CARTODBPOSITRON_RETINA",
            tile_provider_url=None,
            toolbar_location=None,
            show_figure=True,
            return_figure=True,
            return_html=False,
            legend=True,
            **kwargs):
    """Doc-String: TODO"""

    gdf = gdf_in.copy()

    #Check layertypes:
    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(
            "Can only plot GeoDataFrames/Series with single type of geometry (either Point, Line or Polygon). Provided is a GeoDataFrame/Series with types: %s"
            % layertypes)

    #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"
    }
    if not isinstance(figsize, type(None)):
        width, height = figsize
        figure_options["plot_width"] = width
        figure_options["plot_height"] = height

    if not isinstance(fig, type(None)):
        raise NotImplementedError("Parameter <figure> not yet implemented.")

    #Convert GeoDataFrame to Web Mercador Projection:
    gdf.to_crs({'init': 'epsg:3857'}, inplace=True)

    #Simplify shapes if wanted:
    if isinstance(simplify_shapes, numbers.Number):
        if layertypes[0] in ["Line", "Polygon"]:
            gdf["geometry"] = gdf["geometry"].simplify(simplify_shapes)
    elif not isinstance(simplify_shapes, type(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 isinstance(category, type(None)):
        category_options += 1
        category_columns = [category]
    if not isinstance(dropdown, type(None)):
        category_options += 1
        category_columns = dropdown
    if not isinstance(slider, type(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 isinstance(category, type(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(
            "Could not find column '%s' in GeoDataFrame. For <category>, please provide an existing single column of the GeoDataFrame."
            % category)

    #Check for dropdown (multiple choropleth plots via dropdown selection):
    if isinstance(dropdown, type(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(
                    "Could not find column '%s' for <dropdown> in GeoDataFrame. "
                    % col)

    #Check for slider (multiple choropleth plots via slider selection):
    if isinstance(slider, type(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(
                    "Could not find column '%s' for <slider> in GeoDataFrame. "
                    % col)

        if not isinstance(slider_range, type(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 isinstance(colormap, type(None)):
            colormap = blue_colormap
        elif isinstance(colormap, (tuple, list)):
            if len(colormap) > 1:
                pass
            else:
                raise ValueError(
                    "<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 ): %s"
                    % (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(
                    "Could not find <colormap> with name %s. The following predefined colormaps are supported (see also https://bokeh.pydata.org/en/latest/docs/reference/palettes.html ): %s"
                    % (colormap, list(all_palettes.keys())))
        else:
            raise ValueError(
                "<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 ): %s"
                % (list(all_palettes.keys())))
    else:
        if isinstance(color, str):
            colormap = [color]
        else:
            raise ValueError(
                "<color> has to be a string specifying the fill_color of the map glyph."
            )

    #Create Figure to draw:
    if "Point" in layertypes or "Line" in layertypes:
        figure_options["output_backend"] = "webgl"
    p = figure(x_axis_type="mercator",
               y_axis_type="mercator",
               **figure_options)

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

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

    # Hide legend if wanted:
    if not legend:
        p.legend.visible = False
    legend = "GeoLayer"

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

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

        field = category
        colormapper_options = {"palette": colormap}
        if not isinstance(colormap_range, type(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}
        legend = str(field)

    elif not isinstance(dropdown, type(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(
                    "<dropdown> plot only yet implemented for numerical columns. Column '%s' is not numerical."
                    % col)

        field = dropdown[0]
        colormapper_options = {"palette": colormap}
        if not isinstance(colormap_range, type(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 = "Geolayer"  ##str(field)

    elif not isinstance(slider, type(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(
                    "<slider> plot only yet implemented for numerical columns. Column '%s' is not numerical."
                    % col)

        field = slider[0]
        colormapper_options = {"palette": colormap}
        if not isinstance(colormap_range, type(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}
        legend = "Geolayer"  ##str(field)

    #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", df_shapes.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 isinstance(category, type(None)):
                hovertool_columns = [category]
            elif not isinstance(dropdown, type(None)):
                hovertool_columns = dropdown
            elif not isinstance(slider, type(None)):
                hovertool_columns = slider
            else:
                hovertool_columns = []
        else:
            for col in hovertool_columns:
                if col not in gdf.columns:
                    raise ValueError(
                        "Could not find columns '%s' in GeoDataFrame. <hovertool_columns> has to be a list of columns of the GeoDataFrame or the string 'all'."
                        % col)
    else:
        if isinstance(category, type(None)):
            hovertool_columns = []
        else:
            hovertool_columns = [category]

    #Reduce DataFrame to needed columns:
    if category_options == 0:
        gdf = gdf[hovertool_columns + ["geometry"]]
    else:
        gdf = gdf[list(set(hovertool_columns) | set(category_columns)) +
                  ["geometry"]]
        gdf["Colormap"] = gdf[field]
        field = "Colormap"

    #Create GeoJSON DataSource for Plot:
    geo_source = GeoJSONDataSource(geojson=gdf.to_json())

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

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

    if "Polygon" in layertypes:

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

        #Plot polygons:
        p.patches(xs="xs", ys="ys", source=geo_source, legend=legend, **kwargs)

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

    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()

        colorbar = ColorBar(**colorbar_options)

        p.add_layout(colorbar, "right")

    if not isinstance(dropdown, type(None)):
        #Define Dropdown widget:
        dropdown_widget = Dropdown(label="Select Choropleth Layer",
                                   menu=list(zip(dropdown, dropdown)))

        #Define Callback for Dropdown widget:
        callback = CustomJS(args=dict(dropdown_widget=dropdown_widget,
                                      geo_source=geo_source,
                                      p=p),
                            code="""

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

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

        #Add Dropdown widget above the plot:
        layout = column(dropdown_widget, p)

    if not isinstance(slider, type(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;
                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:
        layout = column(slider_widget, p)

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

    # Display plot and if wanted return plot:
    if isinstance(layout, type(None)):
        layout = p

    # 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
Example #19
0
def geoplot(  # noqa C901
    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.layouts import column, row
    from bokeh.models import (
        BasicTicker,
        BoxZoomTool,
        ColorBar,
        ColumnDataSource,
        GeoJSONDataSource,
        HoverTool,
        LinearColorMapper,
        LogColorMapper,
        LogTicker,
        Select,
        Slider,
        WheelZoomTool,
    )
    from bokeh.models.callbacks import CustomJS
    from bokeh.models.widgets import Dropdown
    from bokeh.palettes import all_palettes
    from bokeh.plotting import show

    # 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",
        "match_aspect": True,
    }
    if figsize is not 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 simplify_shapes is not None:
            raise ValueError(
                "<simplify_shapes> parameter only accepts numbers or None.")

    # Check for category, dropdown or slider (choropleth map column):
    category_options = 0
    if category is not None:
        category_options += 1
        category_columns = [category]
    if dropdown is not None:
        category_options += 1
        category_columns = dropdown
    if slider is not 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 slider_range is not 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:
        figure_options["x_axis_label"] = (figure_options["x_axis_label"]
                                          if figure_options["x_axis_label"]
                                          is not None else "Longitute")
        figure_options["y_axis_label"] = (figure_options["y_axis_label"]
                                          if figure_options["y_axis_label"]
                                          is not None else "Latitude")
        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."
        )

    for t in p.tools:
        # Get ridd of zoom on axes:
        if isinstance(t, WheelZoomTool):
            t.zoom_on_axis = False
        # Make sure that box zoom matches aspect:
        if isinstance(t, BoxZoomTool):
            t.match_aspect = True

    # 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 category is not 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 colormap_range is not 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 dropdown is not 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 colormap_range is not 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 slider is not 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 colormap_range is not 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 category is not None:
                hovertool_columns = [category]
            elif dropdown is not None:
                hovertool_columns = dropdown
            elif slider is not 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 dropdown is not 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 slider is not 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
Example #20
0
def create_figure():

    p1, data1, err1 = plot_lya(data_dir,
                               'F125',
                               x_range=(0, 100),
                               y_range=(0, 100))
    p2, data2, err2 = plot_lya(data_dir,
                               'F140',
                               x_range=p1.x_range,
                               y_range=p1.y_range)
    p3, data3, err3 = plot_lya(data_dir,
                               'F150',
                               x_range=p1.x_range,
                               y_range=p1.y_range)
    p4, data4, err4 = plot_lya(data_dir,
                               'F165',
                               x_range=p1.x_range,
                               y_range=p1.y_range)

    TOOLS = " pan,lasso_select, box_select,help,wheel_zoom,box_zoom,reset, tap, undo, redo"

    color_mapper = LogColorMapper(palette="Viridis256",
                                  low=1e-3,
                                  high=1e-2 * 0.5)
    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=LogTicker(),
                         width=5,
                         major_label_text_font_size="5pt",
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))

    p4.add_layout(color_bar, 'center')

    x1 = int(x_plot.value)
    y1 = int(y_plot.value)

    p5 = figure(tools=TOOLS,
                title='errorbars with UV filters and fits',
                width=300,
                height=300)

    p5.xaxis.axis_label = 'wavelength'
    p5.yaxis.axis_label = 'counts'

    xs = np.array([1438.19187645, 1527.99574111, 1612.22929754, 1762.54619064])

    ys = [data1[x1, y1], data2[x1, y1], data3[x1, y1], data4[x1, y1]]
    yerrs = [err1[x1, y1], err2[x1, y1], err3[x1, y1], err4[x1, y1]]

    p5.circle(xs, ys, color='green', size=10, line_alpha=0)

    err_xs = []
    err_ys = []

    for x, y, yerr in zip(xs, ys, yerrs):
        err_xs.append((x, x))
        err_ys.append((y - yerr, y + yerr))

    p5.multi_line(err_xs, err_ys, color='black')

    # show(p)

    A = fits.getdata(data_dir + 'ULIRG%s/A_lmfit_x550_y550_sz100.fits' %
                     (ulirg.value))  #, data = d3, overwrite= True)
    b = fits.getdata(data_dir + 'ULIRG%s/b_lmfit_x550_y550_sz100.fits' %
                     (ulirg.value))  #, data = d3, overwrite= True)
    m = fits.getdata(data_dir + 'ULIRG%s/m_lmfit_x550_y550_sz100.fits' %
                     (ulirg.value))  #, data = d3, overwrite= True)

    A_err = fits.getdata(data_dir +
                         'ULIRG%s/A_lmfit_err_x550_y550_sz100.fits' %
                         (ulirg.value))  #, data = d3, overwrite= True)

    A_cut = A[550:650, 550:650]
    b_cut = b[550:650, 550:650]
    m_cut = m[550:650, 550:650]

    A_err_cut = A[550:650, 550:650]

    y_fitted, spec = counts_out(m_cut[x1, y1], b_cut[x1, y1], A_cut[x1, y1])

    p5.x(xs, y_fitted, color='red', size=15)


    p6 = figure(tools= TOOLS, title='spectrum',x_range=(1200, 1900),\
     width=300, height=300, y_axis_type="log",x_axis_type="log", background_fill_color="#fafafa")

    p6.xaxis.axis_label = 'wavelength'
    p6.yaxis.axis_label = 'flux'

    wave1 = np.arange(1000, 10000, 1.0)

    p6.line(wave1, spec, color='blue', line_width=1.0)

    p7 = figure(title='ULIRG%s, LYA ' % (ulirg.value),
                tools=TOOLS,
                plot_width=300,
                plot_height=300,
                x_range=p1.x_range,
                y_range=p1.y_range,
                tooltips=[("x", "$x"), ("y", "$y"), ("LYA", "@image"),
                          ("ERR", "@A_err_cut")])

    # must give a vector of image data for image parameter

    data_lya = dict(image=[A_cut], A_err_cut=[A_err_cut])

    color_mapper = LogColorMapper(
        palette="Greys256")  #, low=1e-3, high=1e-2*0.5)

    p7.image(source=data_lya,
             image='image',
             x=0,
             y=0,
             dw=100,
             dh=100,
             color_mapper=color_mapper)

    p7.x([float(x_plot.value)], [float(y_plot.value)],
         size=25,
         color="red",
         alpha=2.0)

    p = gridplot([[p1, p2, p6], [p3, p4, p5], [p7]])

    return row(
        p,
        column(widgetbox(button),
               widgetbox(table_values(ulirg, x_plot, y_plot)), widgetbox(pre)))
def get_world_map_plot(summary, value):
    value_per_country = group_value_by_country(summary, value)
    max_value = max(value_per_country.values()) if len(
        value_per_country.values()) > 0 else 0
    min_value = min(value_per_country.values()) if len(
        value_per_country.values()) > 0 else 0
    abs_max_value = abs(min_value) if abs(min_value) > abs(max_value) else abs(
        max_value)
    with open('resources/world_map.json') as f:
        data = json.load(f)
    # No need for Antarctica
    data['features'].pop(6)
    to_be_plotted = data.copy()
    to_be_plotted["features"] = []

    empty_countries = data.copy()
    empty_countries["features"] = []
    if min_value >= 0:
        cmap = matplotlib.cm.get_cmap('inferno')
    else:
        cmap = matplotlib.cm.get_cmap('RdYlGn')
    for i in range(len(data['features'])):
        country = data['features'][i]['id']
        if country in value_per_country:
            data['features'][i]['properties']['amount'] = value_per_country[
                country]
            if min_value < 0:
                n_value = (value_per_country[country] +
                           abs_max_value) / (2 * abs_max_value)
                data['features'][i]['properties']['color'] = n_value
            else:
                data['features'][i]['properties']['color'] = np.log(
                    value_per_country[country]) / np.log(max_value)
            to_be_plotted["features"].append(data['features'][i])
        else:
            data['features'][i]['properties']['amount'] = 0
            empty_countries["features"].append(data['features'][i])
    geo_source = GeoJSONDataSource(geojson=json.dumps(data))
    p = figure(background_fill_color="lightgrey",
               sizing_mode='scale_width',
               toolbar_location=None,
               aspect_ratio=1920.0 / 920)
    temp_geo_source = GeoJSONDataSource(geojson=json.dumps(empty_countries))
    p.patches('xs', 'ys', source=temp_geo_source, color='grey')
    for i in range(len(to_be_plotted['features'])):
        temp_data = to_be_plotted.copy()
        temp_data['features'] = [temp_data['features'][i]]
        temp_geo_source = GeoJSONDataSource(geojson=json.dumps(temp_data))
        ratio = temp_data['features'][0]['properties']['color']
        color = cmap(ratio)
        amount_plot = p.patches('xs',
                                'ys',
                                source=temp_geo_source,
                                color=RGB(color[0] * 255, color[1] * 255,
                                          color[2] * 255))
        p.add_tools(
            HoverTool(tooltips=[("Country", "@name"),
                                ("Invested", "@amount{%0.2f}")],
                      formatters={'@amount': 'printf'},
                      renderers=[amount_plot]))

    p.multi_line('xs',
                 'ys',
                 source=geo_source,
                 color='cornsilk',
                 line_width=1.5)
    colors = [matplotlib.colors.rgb2hex(cmap(i / 256.0)) for i in range(256)]
    if min_value >= 0:
        color_mapper = LogColorMapper(palette=colors, low=1, high=max_value)
        ticks = LogTicker()
    else:
        color_mapper = LinearColorMapper(palette=colors,
                                         low=-abs_max_value,
                                         high=abs_max_value)
        ticks = BasicTicker()
    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=ticks,
                         border_line_color=None,
                         location=(0, 0),
                         background_fill_alpha=0.,
                         label_standoff=12)
    color_bar.major_label_text_color = "white"
    p.add_layout(color_bar, 'right')
    p.background_fill_alpha = 0.
    p.xgrid.grid_line_color = None
    p.ygrid.grid_line_color = None
    p.toolbar.active_drag = None
    p.border_fill_alpha = 0.
    p.outline_line_alpha = 0.
    p.axis.visible = False
    p.xaxis.major_tick_line_color = None  # turn off x-axis major ticks
    p.xaxis.minor_tick_line_color = None  # turn off x-axis minor ticks
    p.yaxis.major_tick_line_color = None  # turn off y-axis major ticks
    p.yaxis.minor_tick_line_color = None  # turn off y-axis minor ticks
    script, world_map = components(p)
    return {
        "world_map_script_" + value: script,
        "world_map_plot_" + value: world_map
    }
Example #22
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)
#
# x = np.linspace(0, 4*np.pi, 100)
# y = np.sin(x)
#
# output_file("legend.html")
#
# p = figure()
#
# p.circle(x, y, legend="sin(x)")
# p.line(x, y, legend="sin(x)")
Example #23
0
def create_plots(state, oil_prod, unemp, lab_force):
    target_state = (state)
    state_dict = {'tx': 'Texas', 'nd': 'North Dakota', 'wy': 'Wyoming'}

    min_date = max(min(unemp.index), min(oil_prod.index))
    max_date = min(max(unemp.index), max(oil_prod.index))

    cur_sp500 = sp500.loc[min_date:max_date]
    source_sp500 = ColumnDataSource(cur_sp500)

    cur_oil_price = oil_price.loc[min_date:max_date]
    source_oil_price = ColumnDataSource(cur_oil_price)

    oil_prod = oil_prod.loc[min_date:max_date]
    unemp = unemp.loc[min_date:max_date]
    lab_force = lab_force.loc[min_date:max_date]

    county_xs = [
        counties[code]["lons"] for code in counties
        if counties[code]["state"] in target_state
    ]
    county_ys = [
        counties[code]["lats"] for code in counties
        if counties[code]["state"] in target_state
    ]

    county_names = unemp.columns
    county_rates = unemp.loc[cur_date].values[0]
    county_prods = oil_prod.loc[cur_date].values[0]

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

    source_maps = ColumnDataSource(data=dict(x=county_xs,
                                             y=county_ys,
                                             name=county_names,
                                             rate=county_rates,
                                             prod=county_prods))

    unemp_color_mapper = LogColorMapper(palette="Viridis256",
                                        low=max(min(county_rates), 0.1),
                                        high=max(county_rates))

    fig_unemp = figure(title='%s unemployment rate for %s, %d' %
                       (state_dict[state], month_dict[cur_month], cur_year),
                       toolbar_location="left",
                       tools=TOOLS,
                       plot_width=500,
                       plot_height=450)

    pyglyph = fig_unemp.patches(
        'x',
        'y',
        source=source_maps,
        fill_color={
            'field': 'rate',
            'transform': unemp_color_mapper
        },
        fill_alpha=0.7,
        line_color="white",
        line_width=0.5,
        # set visual properties for selected glyphs
        selection_color="firebrick",

        # set visual properties for non-selected glyphs
        nonselection_fill_alpha=0.2,
        nonselection_fill_color="blue",
        nonselection_line_color="firebrick",
        nonselection_line_alpha=1.0)

    hover_unemp = fig_unemp.select(HoverTool)
    hover_unemp.point_policy = "follow_mouse"
    hover_unemp.tooltips = [
        ("Name", "@name"),
        ("Unemployment rate", "@rate%"),
        ("(Long, Lat)", "($x, $y)"),
    ]

    unemp_color_bar = ColorBar(color_mapper=unemp_color_mapper,
                               ticker=LogTicker(),
                               border_line_color=None,
                               location=(0, 0))
    fig_unemp.add_layout(unemp_color_bar, 'right')

    prod_color_mapper = LogColorMapper(palette="BuGn7",
                                       low=max(min(county_prods), 0.1),
                                       high=max(county_prods))

    fig_prods = figure(title='%s production data for %s, %d' %
                       (state_dict[state], month_dict[cur_month], cur_year),
                       toolbar_location="left",
                       tools=TOOLS,
                       plot_width=500,
                       plot_height=450)

    pyglyph_prod = fig_prods.patches(
        'x',
        'y',
        source=source_maps,
        fill_color={
            'field': 'prod',
            'transform': prod_color_mapper
        },
        fill_alpha=0.7,
        line_color="grey",
        line_width=0.5,
        # set visual properties for selected glyphs
        selection_color="firebrick",

        # set visual properties for non-selected glyphs
        nonselection_fill_alpha=0.2,
        nonselection_fill_color="blue",
        nonselection_line_color="firebrick",
        nonselection_line_alpha=1.0)

    hover_prod = fig_prods.select(HoverTool)
    hover_prod.point_policy = "follow_mouse"
    hover_prod.tooltips = [
        ("Name", "@name"),
        ("Production", "@prod bbls"),
        ("(Long, Lat)", "($x, $y)"),
    ]

    prod_color_bar = ColorBar(color_mapper=prod_color_mapper,
                              ticker=LogTicker(),
                              label_standoff=12,
                              border_line_color=None,
                              location=(0, 0))
    fig_prods.add_layout(prod_color_bar, 'right')

    cur_county = county_names[0]
    source_oil = ColumnDataSource(
        data=dict(date=oil_prod.index, oil_prod=oil_prod[cur_county]))

    fig1 = figure(title='Employment vs Oil prices for ' + cur_county,
                  x_axis_type='datetime',
                  plot_width=700,
                  plot_height=400,
                  toolbar_location='left',
                  tools=TOOLS)

    source_figures = ColumnDataSource(
        dict(date=unemp.index,
             unemp=unemp[cur_county],
             lab_force=lab_force[cur_county]))

    fig1.circle('Date',
                'WTI',
                source=source_oil_price,
                legend="Oil Price, $",
                selection_color='red',
                nonselection_fill_color='grey',
                nonselection_fill_alpha=0.2)
    fig1.line('Date', 'WTI', source=source_oil_price, legend="Oil Price, $")
    fig1.xaxis.axis_label = 'Date'
    fig1.yaxis.axis_label = 'Oil Price, $ (month avg.)'
    fig1.y_range = Range1d(start=0, end=150)

    # Adding second y axis for unemployment
    fig1.extra_y_ranges['unemp'] = Range1d(start=0, end=50)
    fig1.add_layout(
        LinearAxis(y_range_name="unemp", axis_label='Unemployment Rate (%)'),
        'right')

    # Adding third y axis for labor force
    fig1.extra_y_ranges['labforce'] = Range1d(
        start=max(100,
                  min(lab_force[cur_county]) - 1000),
        end=max(lab_force[cur_county]) + 1000)
    fig1.add_layout(
        LogAxis(y_range_name="labforce", axis_label='Labor Force (log)'),
        'right')

    fig1.circle('date',
                'unemp',
                source=source_figures,
                y_range_name="unemp",
                legend="Unemployment rate (%)",
                color='orange')
    fig1.line('date',
              'unemp',
              source=source_figures,
              y_range_name="unemp",
              legend="Unemployment rate (%)",
              color='orange')

    fig1.circle('date',
                'lab_force',
                source=source_figures,
                y_range_name="labforce",
                legend="Labor Force (log)",
                color='green')
    fig1.line('date',
              'lab_force',
              source=source_figures,
              y_range_name="labforce",
              legend="Labor Force (log)",
              color='green')
    fig1.legend.location = 'top_left'
    fig1.legend.label_text_font_size = '8pt'

    fig2 = figure(title='Employment vs Oil production for ' + cur_county,
                  x_axis_type='datetime',
                  plot_width=700,
                  plot_height=400,
                  toolbar_location='left',
                  tools=TOOLS)
    fig2.circle('date',
                'oil_prod',
                source=source_oil,
                legend='Oil production (bbls)',
                hover_color='red',
                selection_color='red',
                nonselection_fill_color='grey',
                nonselection_fill_alpha=0.2)
    fig2.xaxis.axis_label = 'Date'
    fig2.yaxis.axis_label = 'Oil Production (bbls)'
    fig2.y_range = Range1d(start=max(0,
                                     min(oil_prod[cur_county]) - 1000),
                           end=max(oil_prod[cur_county]) + 1000)

    # Adding second y axis for unemployment
    fig2.extra_y_ranges['unemp'] = Range1d(start=0, end=50)
    fig2.add_layout(
        LinearAxis(y_range_name="unemp", axis_label='Unemployment Rate (%)'),
        'right')

    # Adding third y axis for labor force
    fig2.extra_y_ranges['labforce'] = Range1d(
        start=max(100,
                  min(lab_force[cur_county]) - 1000),
        end=max(lab_force[cur_county] + 1000))
    fig2.add_layout(
        LogAxis(y_range_name="labforce", axis_label='Labor Force (log)'),
        'right')

    fig2.circle('date',
                'unemp',
                source=source_figures,
                y_range_name="unemp",
                legend="Unemployment rate (%)",
                color='orange')
    fig2.line('date',
              'unemp',
              source=source_figures,
              y_range_name="unemp",
              legend="Unemployment rate (%)",
              color='orange')

    fig2.circle('date',
                'lab_force',
                source=source_figures,
                y_range_name="labforce",
                legend="Labor Force (log)",
                color='green')
    fig2.line('date',
              'lab_force',
              source=source_figures,
              y_range_name="labforce",
              legend="Labor Force (log)",
              color='green')
    fig2.legend.location = 'top_left'
    fig2.legend.label_text_font_size = '8pt'

    fig3 = figure(title='Employment vs S&P 500 for ' + cur_county,
                  x_axis_type='datetime',
                  plot_width=700,
                  plot_height=400,
                  toolbar_location='left',
                  tools=TOOLS)
    fig3.circle('Date',
                'SP500',
                source=source_sp500,
                legend='S&P 500 index',
                hover_color='red',
                selection_color='red',
                nonselection_fill_color='grey',
                nonselection_fill_alpha=0.2)
    fig3.xaxis.axis_label = 'Date'
    fig3.yaxis.axis_label = 'S&P 500 index'
    fig3.y_range = Range1d(start=0, end=max(sp500['SP500']))

    # Adding second y axis for unemployment
    fig3.extra_y_ranges['unemp'] = Range1d(start=0, end=50)
    fig3.add_layout(
        LinearAxis(y_range_name="unemp", axis_label='Unemployment Rate (%)'),
        'right')

    # Adding third y axis for labor force
    fig3.extra_y_ranges['labforce'] = Range1d(
        start=max(100,
                  min(lab_force[cur_county]) - 1000),
        end=max(lab_force[cur_county] + 1000))
    fig3.add_layout(
        LogAxis(y_range_name="labforce", axis_label='Labor Force (log)'),
        'right')

    fig3.circle('date',
                'unemp',
                source=source_figures,
                y_range_name="unemp",
                legend="Unemployment rate (%)",
                color='orange')
    fig3.line('date',
              'unemp',
              source=source_figures,
              y_range_name="unemp",
              legend="Unemployment rate (%)",
              color='orange')

    fig3.circle('date',
                'lab_force',
                source=source_figures,
                y_range_name="labforce",
                legend="Labor Force (log)",
                color='green')
    fig3.line('date',
              'lab_force',
              source=source_figures,
              y_range_name="labforce",
              legend="Labor Force (log)",
              color='green')
    fig3.legend.location = 'top_left'
    fig3.legend.label_text_font_size = '8pt'

    def fig_callback_tap(attr, old, new):
        try:
            # The index of the selected glyph is : new['1d']['indices'][0]
            selections = new['1d']['indices']
            patch_name = source_maps.data['name'][selections[0]]
            source_figures.data = dict(date=unemp.index,
                                       unemp=unemp[patch_name],
                                       lab_force=lab_force[patch_name])
            source_oil.data = dict(date=oil_prod.index,
                                   oil_prod=oil_prod[patch_name])
        except:
            selections = old['1d']['indices']
            patch_name = source_maps.data['name'][selections[0]]
            source_figures.data = dict(date=unemp.index,
                                       unemp=unemp[patch_name],
                                       lab_force=lab_force[patch_name])
            source_oil.data = dict(date=oil_prod.index,
                                   oil_prod=oil_prod[patch_name])

        fig1.title.text = 'Employment vs Oil prices for ' + patch_name
        fig2.title.text = 'Employment vs Oil production for ' + patch_name
        fig3.title.text = 'Employment vs S&P 500 for ' + patch_name
        fig2.y_range.start = max(0, min(oil_prod[patch_name]) - 1000)
        fig2.y_range.end = max(oil_prod[patch_name]) + 1000

        fig1.extra_y_ranges['labforce'].start = max(
            100,
            min(lab_force[patch_name]) - 1000)
        fig1.extra_y_ranges['labforce'].end = max(lab_force[patch_name] + 1000)
        fig2.extra_y_ranges['labforce'].start = max(
            100,
            min(lab_force[patch_name]) - 1000)
        fig2.extra_y_ranges['labforce'].end = max(lab_force[patch_name] + 1000)
        fig3.extra_y_ranges['labforce'].start = max(
            100,
            min(lab_force[patch_name]) - 1000)
        fig3.extra_y_ranges['labforce'].end = max(lab_force[patch_name] + 1000)

    pyglyph.data_source.on_change('selected', fig_callback_tap)
    pyglyph_prod.data_source.on_change('selected', fig_callback_tap)

    def update_plot_yr(attr, old, new):
        # Assign the value of the slider: new_year
        new_year = slider_yr.value
        new_month = slider_month.value

        new_date = pd.to_datetime({
            'year': [new_year],
            'month': [new_month],
            'day': [1]
        })
        new_rates = unemp.loc[new_date].values[0]
        new_prods = oil_prod.loc[new_date].values[0]

        # Set new_data
        new_data = dict(x=county_xs,
                        y=county_ys,
                        name=county_names,
                        rate=new_rates,
                        prod=new_prods)

        # Assign new_data to: source.data
        source_maps.data = new_data

        # Add title to figure: plot.title.text
        fig_unemp.title.text = '%s unemployment rate for %s, %d' % (
            state_dict[state], month_dict[new_month], new_year)

        # Add title to figure: plot.title.text
        fig_prods.title.text = '%s production data for %s, %d' % (
            state_dict[state], month_dict[new_month], new_year)

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

    # Attach the callback to the 'value' property of slider
    slider_yr.on_change('value', update_plot_yr)

    # Make a slider object: slider
    slider_month = Slider(title='Month',
                          start=1,
                          end=12,
                          step=1,
                          value=cur_month)

    # Attach the callback to the 'value' property of slider
    slider_month.on_change('value', update_plot_yr)

    return fig_unemp, fig_prods, fig1, fig2, fig3, slider_yr, slider_month
Example #24
0
    def ConfirmedMapPlot(self):
        # Get the tile provider
        tile_provider = get_provider(CARTODBPOSITRON)

        # Create the plot
        plot = figure(x_axis_type="mercator", 
                      y_axis_type="mercator",
                      title=self.title, 
                      tools = 'pan, wheel_zoom, reset',
                      active_drag   = 'pan',
                      active_scroll = 'wheel_zoom')

        # Add the tile streamer to the plot
        plot.add_tile(tile_provider)

        # Set the sizing mode
        plot.sizing_mode = 'stretch_both'

        # Transform from WGS83 to Web Mercator projection
        merc_geo_json_df = self.country_data.to_crs('EPSG:3857')

        # Add the transformed data to a GeoJSONDataSource
        geosource = GeoJSONDataSource(geojson = merc_geo_json_df.to_json())

        # Set the palette and min/max range for the colour mapper
        palette = brewer[self.colour][8]
        palette = palette[::-1]
        min_range = self.country_data[self.column].min()
        max_range = self.country_data[self.column].max()

        # Create the colour mapper
        color_mapper = LogColorMapper(palette = palette, low = min_range, high = max_range)

        # Create a tick formatter
        format_tick = NumeralTickFormatter(format='0.0a')

        # Create a Log Ticker
        log_ticker = LogTicker()

        # Create the colour bar which will go on the right
        color_bar = ColorBar(color_mapper=color_mapper,
                             label_standoff=18,
                             formatter=format_tick,
                             border_line_color=None,
                             location = (0, 0),
                             ticker=log_ticker)

        # Add the data to the circle plot
        plot.patches(xs='xs', 
                     ys='ys', 
                     source=geosource, 
                     line_color=self.line_colour,
                     fill_alpha=0.8, 
                     fill_color={'field' : self.column, 'transform' : color_mapper})

        # Add the colour bar
        plot.add_layout(color_bar, 'right')

        # Add the tooltip
        self.AddToolTip(plot, self.tooltips)

        curdoc().add_root(plot)
Example #25
0
def make_tpf_figure_elements(tpf,
                             tpf_source,
                             pedestal=None,
                             fiducial_frame=None,
                             plot_width=370,
                             plot_height=340):
    """Returns the lightcurve figure elements.

    Parameters
    ----------
    tpf : TargetPixelFile
        TPF to show.
    tpf_source : bokeh.plotting.ColumnDataSource
        TPF data source.
    pedestal: float
        A scalar value to be added to the TPF flux values, often to avoid
        taking the log of a negative number in colorbars.
        Defaults to `-min(tpf.flux) + 1`
    fiducial_frame: int
        The tpf slice to start with by default, it is assumed the WCS
        is exact for this frame.

    Returns
    -------
    fig, stretch_slider : bokeh.plotting.figure.Figure, RangeSlider
    """
    if pedestal is None:
        pedestal = -np.nanmin(tpf.flux) + 1

    if tpf.mission in ['Kepler', 'K2']:
        title = 'Pixel data (CCD {}.{})'.format(tpf.module, tpf.output)
    elif tpf.mission == 'TESS':
        title = 'Pixel data (Camera {}.{})'.format(tpf.camera, tpf.ccd)
    else:
        title = "Pixel data"

    fig = figure(plot_width=plot_width,
                 plot_height=plot_height,
                 x_range=(tpf.column, tpf.column + tpf.shape[2]),
                 y_range=(tpf.row, tpf.row + tpf.shape[1]),
                 title=title,
                 tools='tap,box_select,wheel_zoom,reset',
                 toolbar_location="below",
                 border_fill_color="whitesmoke")

    fig.yaxis.axis_label = 'Pixel Row Number'
    fig.xaxis.axis_label = 'Pixel Column Number'

    vlo, lo, hi, vhi = np.nanpercentile(tpf.flux + pedestal,
                                        [0.2, 1, 95, 99.8])
    vstep = (np.log10(vhi) - np.log10(vlo)) / 300.0  # assumes counts >> 1.0!
    color_mapper = LogColorMapper(palette="Viridis256", low=lo, high=hi)

    fig.image([tpf.flux[fiducial_frame, :, :] + pedestal],
              x=tpf.column,
              y=tpf.row,
              dw=tpf.shape[2],
              dh=tpf.shape[1],
              dilate=True,
              color_mapper=color_mapper,
              name="tpfimg")

    # The colorbar will update with the screen stretch slider
    # The colorbar margin increases as the length of the tick labels grows.
    # This colorbar share of the plot window grows, shrinking plot area.
    # This effect is known, some workarounds might work to fix the plot area:
    # https://github.com/bokeh/bokeh/issues/5186
    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=LogTicker(desired_num_ticks=8),
                         label_standoff=-10,
                         border_line_color=None,
                         location=(0, 0),
                         background_fill_color='whitesmoke',
                         major_label_text_align='left',
                         major_label_text_baseline='middle',
                         title='e/s',
                         margin=0)
    fig.add_layout(color_bar, 'right')

    color_bar.formatter = PrintfTickFormatter(format="%14u")

    if tpf_source is not None:
        fig.rect('xx',
                 'yy',
                 1,
                 1,
                 source=tpf_source,
                 fill_color='gray',
                 fill_alpha=0.4,
                 line_color='white')

    # Configure the stretch slider and its callback function
    stretch_slider = RangeSlider(start=np.log10(vlo),
                                 end=np.log10(vhi),
                                 step=vstep,
                                 title='Screen Stretch (log)',
                                 value=(np.log10(lo), np.log10(hi)),
                                 orientation='horizontal',
                                 width=200,
                                 height=10,
                                 direction='ltr',
                                 show_value=True,
                                 sizing_mode='fixed',
                                 name='tpfstretch')

    def stretch_change_callback(attr, old, new):
        """TPF stretch slider callback."""
        fig.select('tpfimg')[0].glyph.color_mapper.high = 10**new[1]
        fig.select('tpfimg')[0].glyph.color_mapper.low = 10**new[0]

    stretch_slider.on_change('value', stretch_change_callback)

    return fig, stretch_slider
from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.palettes import Spectral6
from bokeh.transform import log_cmap
from bokeh.models import ColorBar, LogTicker
import numpy as np

x = np.linspace(1, 10, 100)
y = np.exp(x)

mapper = log_cmap(field_name='y', palette=Spectral6, low=min(y), high=max(y))

plot = figure(plot_height=300, plot_width=600)
plot.circle(x, y, color=mapper, line_color='black', size=10)

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

plot.add_layout(color_bar, 'right')

output_file('color_mapper.html')
show(plot)
Example #27
0
def plot_cld_input(nwno,
                   nlayer,
                   filename=None,
                   df=None,
                   pressure=None,
                   wavelength=None,
                   **pd_kwargs):
    """
    This function was created to investigate CLD input file for PICASO. 

    The plot itselfs creates maps of the wavelength dependent single scattering albedo 
    and cloud opacity and assymetry parameter as a function of altitude. 


    Parameters
    ----------
    nwno : int 
        Number of wavenumber points. For runs from Ackerman & Marley, this will always be 196. 
    nlayer : int 
        Should be one less than the number of levels in your pressure temperature grid. Cloud 
        opacity is assigned for slabs. 
    file : str , optional
        (Optional)Path to cloud input file
    df : str 
        (Optional)Dataframe of cloud input file
    wavelength : array , optional
        (Optional) this allows you to reset the tick marks to wavelengths instead of indicies 
    pressure : array, optional 
        (Optional) this allows you to reset the tick marks to pressure instead of indicies  
    pd_kwargs : kwargs
        Pandas key word arguments for `pandas.read_csv`

    Returns
    -------
    Three bokeh plots with the single scattering, optical depth, and assymetry maps
    """
    if (pressure is not None):
        pressure_label = 'Pressure (units by user)'
    else:
        pressure_label = 'Pressure Grid, TOA ->'
    if (wavelength is not None):
        wavelength_label = 'Wavelength (units by user)'
    else:
        wavelength_label = 'Wavenumber Grid'
    cols = colfun1(200)
    color_mapper = LinearColorMapper(palette=cols, low=0, high=1)

    if not isinstance(filename, type(None)):
        dat01 = pd.read_csv(filename, **pd_kwargs)
    elif not isinstance(df, type(None)):
        dat01 = df

    #PLOT W0
    scat01 = np.flip(np.reshape(dat01['w0'].values, (nlayer, nwno)), 0)
    xr, yr = scat01.shape
    f01a = figure(x_range=[0, yr],
                  y_range=[0, xr],
                  x_axis_label=wavelength_label,
                  y_axis_label=pressure_label,
                  title="Single Scattering Albedo",
                  plot_width=300,
                  plot_height=300)

    f01a.image(image=[scat01],
               color_mapper=color_mapper,
               x=0,
               y=0,
               dh=xr,
               dw=yr)

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

    f01a.add_layout(color_bar, 'left')

    #PLOT OPD
    scat01 = np.flip(np.reshape(dat01['opd'].values, (nlayer, nwno)), 0)

    xr, yr = scat01.shape
    cols = colfun2(200)[::-1]
    color_mapper = LogColorMapper(palette=cols, low=1e-3, high=10)

    f01 = figure(x_range=[0, yr],
                 y_range=[0, xr],
                 x_axis_label=wavelength_label,
                 y_axis_label=pressure_label,
                 title="Cloud Optical Depth Per Layer",
                 plot_width=300,
                 plot_height=300)

    f01.image(image=[scat01],
              color_mapper=color_mapper,
              x=0,
              y=0,
              dh=xr,
              dw=yr)

    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=LogTicker(),
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))
    f01.add_layout(color_bar, 'left')

    #PLOT G0
    scat01 = np.flip(np.reshape(dat01['g0'].values, (nlayer, nwno)), 0)

    xr, yr = scat01.shape
    cols = colfun3(200)[::-1]
    color_mapper = LinearColorMapper(palette=cols, low=0, high=1)

    f01b = figure(x_range=[0, yr],
                  y_range=[0, xr],
                  x_axis_label=wavelength_label,
                  y_axis_label=pressure_label,
                  title="Assymetry Parameter",
                  plot_width=300,
                  plot_height=300)

    f01b.image(image=[scat01],
               color_mapper=color_mapper,
               x=0,
               y=0,
               dh=xr,
               dw=yr)

    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=BasicTicker(),
                         label_standoff=12,
                         border_line_color=None,
                         location=(0, 0))
    f01b.add_layout(color_bar, 'left')

    #CHANGE X AND Y AXIS TO BE PHYSICAL UNITS
    #indexes for pressure plot
    if (pressure is not None):
        pressure = ["{:.1E}".format(i) for i in pressure[::-1]
                    ]  #flip since we are also flipping matrices
        npres = len(pressure)
        ipres = np.array(range(npres))
        #set how many we actually want to put on the figure
        #hard code ten on each..
        ipres = ipres[::int(npres / 10)]
        pressure = pressure[::int(npres / 10)]
        #create dictionary for tick marks
        ptick = {int(i): j for i, j in zip(ipres, pressure)}
        for i in [f01a, f01, f01b]:
            i.yaxis.ticker = ipres
            i.yaxis.major_label_overrides = ptick
    if (wavelength is not None):
        wave = ["{:.2F}".format(i) for i in wavelength]
        nwave = len(wave)
        iwave = np.array(range(nwave))
        iwave = iwave[::int(nwave / 10)]
        wave = wave[::int(nwave / 10)]
        wtick = {int(i): j for i, j in zip(iwave, wave)}
        for i in [f01a, f01, f01b]:
            i.xaxis.ticker = iwave
            i.xaxis.major_label_overrides = wtick

    return row(f01a, f01, f01b)
def create_world_map_tab():
    "Factory for creating first tab of app."

    ## Data Sources
    source_df, source_CDS = get_time_series_confirmed_data()

    ## Map
    color_mapper = log_cmap(field_name='number',
                            palette=Spectral6,
                            low=1,
                            high=1e6)

    TOOLTIPS = [('Region', '@full_name'), ('Num. Cases', '@number{0,0}')]

    map_figure = figure(title='Confirmed COVID-19 Cases by Region',
                        tooltips=TOOLTIPS,
                        x_range=(-16697923.62, 18924313),
                        y_range=(-8399737.89, 8399737.89),
                        x_axis_type='mercator',
                        y_axis_type='mercator',
                        active_scroll='wheel_zoom')

    tile_provider = get_provider(CARTODBPOSITRON)
    map_figure.add_tile(tile_provider)
    map_figure.circle(x='web_mercator_x',
                      y='web_mercator_y',
                      source=source_CDS,
                      size='sizes',
                      color=color_mapper)

    ## Colorbar
    color_bar = ColorBar(title='Num. Cases',
                         title_standoff=20,
                         color_mapper=color_mapper['transform'],
                         label_standoff=20,
                         width=8,
                         location=(0, 0),
                         ticker=LogTicker())
    color_bar.formatter.use_scientific = False
    map_figure.add_layout(color_bar, 'right')

    ## Slider
    def slider_callback(attr, old, new):
        delta = datetime.timedelta(milliseconds=new)
        date = datetime.date(1970, 1, 1) + delta
        date_string = date.strftime('%Y-%m-%d')

        try:
            source_CDS.data['number'] = source_df[date_string]
            source_CDS.data['sizes'] = source_df[date_string].apply(scale)
        except KeyError:
            pass

    slider = DateSlider(title='Date',
                        start=START_DATE,
                        end=datetime.date.today(),
                        step=1,
                        value=START_DATE)
    slider.on_change('value', slider_callback)

    ## Data Table
    columns = [
        TableColumn(field='full_name', title='Region'),
        TableColumn(field='number', title='Cases')
    ]

    data_table = DataTable(
        source=source_CDS,
        columns=columns,
    )

    ## Cancel Selection Button
    def cancel_selection_callback():
        source_CDS.selected.indices = []

    cancel_selection_button = Button(label='Clear Selection',
                                     button_type='warning')
    cancel_selection_button.on_click(cancel_selection_callback)

    child = row([
        column([slider, map_figure]),
        column([data_table, cancel_selection_button]),
    ])

    return Panel(child=child, title='World Map')
Example #29
0
def make_tpf_figure_elements(tpf,
                             tpf_source,
                             pedestal=None,
                             fiducial_frame=None,
                             plot_width=370,
                             plot_height=340,
                             scale='log',
                             vmin=None,
                             vmax=None,
                             cmap='Viridis256',
                             tools='tap,box_select,wheel_zoom,reset'):
    """Returns the lightcurve figure elements.

    Parameters
    ----------
    tpf : TargetPixelFile
        TPF to show.
    tpf_source : bokeh.plotting.ColumnDataSource
        TPF data source.
    pedestal: float
        A scalar value to be added to the TPF flux values, often to avoid
        taking the log of a negative number in colorbars.
        Defaults to `-min(tpf.flux) + 1`
    fiducial_frame: int
        The tpf slice to start with by default, it is assumed the WCS
        is exact for this frame.
    scale: str
        Color scale for tpf figure. Default is 'log'
    vmin: int [optional]
        Minimum color scale for tpf figure
    vmax: int [optional]
        Maximum color scale for tpf figure
    cmap: str
        Colormap to use for tpf plot. Default is 'Viridis256'
    tools: str
        Bokeh tool list
    Returns
    -------
    fig, stretch_slider : bokeh.plotting.figure.Figure, RangeSlider
    """
    if pedestal is None:
        pedestal = -np.nanmin(tpf.flux.value) + 1
    if scale == 'linear':
        pedestal = 0

    if tpf.mission in ['Kepler', 'K2']:
        title = 'Pixel data (CCD {}.{})'.format(tpf.module, tpf.output)
    elif tpf.mission == 'TESS':
        title = 'Pixel data (Camera {}.{})'.format(tpf.camera, tpf.ccd)
    else:
        title = "Pixel data"

    # We subtract 0.5 from the range below because pixel coordinates refer to
    # the middle of a pixel, e.g. (col, row) = (10.0, 20.0) is a pixel center.
    fig = figure(plot_width=plot_width,
                 plot_height=plot_height,
                 x_range=(tpf.column - 0.5, tpf.column + tpf.shape[2] - 0.5),
                 y_range=(tpf.row - 0.5, tpf.row + tpf.shape[1] - 0.5),
                 title=title,
                 tools=tools,
                 toolbar_location="below",
                 border_fill_color="whitesmoke")

    fig.yaxis.axis_label = 'Pixel Row Number'
    fig.xaxis.axis_label = 'Pixel Column Number'

    vlo, lo, hi, vhi = np.nanpercentile(tpf.flux.value + pedestal,
                                        [0.2, 1, 95, 99.8])
    if vmin is not None:
        vlo, lo = vmin, vmin
    if vmax is not None:
        vhi, hi = vmax, vmax

    if scale == 'log':
        vstep = (np.log10(vhi) -
                 np.log10(vlo)) / 300.0  # assumes counts >> 1.0!
    if scale == 'linear':
        vstep = (vhi - vlo) / 300.0  # assumes counts >> 1.0!

    if scale == 'log':
        color_mapper = LogColorMapper(palette=cmap, low=lo, high=hi)
    elif scale == 'linear':
        color_mapper = LinearColorMapper(palette=cmap, low=lo, high=hi)
    else:
        raise ValueError(
            'Please specify either `linear` or `log` scale for color.')

    fig.image([tpf.flux.value[fiducial_frame, :, :] + pedestal],
              x=tpf.column - 0.5,
              y=tpf.row - 0.5,
              dw=tpf.shape[2],
              dh=tpf.shape[1],
              dilate=True,
              color_mapper=color_mapper,
              name="tpfimg")

    # The colorbar will update with the screen stretch slider
    # The colorbar margin increases as the length of the tick labels grows.
    # This colorbar share of the plot window grows, shrinking plot area.
    # This effect is known, some workarounds might work to fix the plot area:
    # https://github.com/bokeh/bokeh/issues/5186

    if scale == 'log':
        ticker = LogTicker(desired_num_ticks=8)
    elif scale == 'linear':
        ticker = BasicTicker(desired_num_ticks=8)

    color_bar = ColorBar(color_mapper=color_mapper,
                         ticker=ticker,
                         label_standoff=-10,
                         border_line_color=None,
                         location=(0, 0),
                         background_fill_color='whitesmoke',
                         major_label_text_align='left',
                         major_label_text_baseline='middle',
                         title='e/s',
                         margin=0)
    fig.add_layout(color_bar, 'right')

    color_bar.formatter = PrintfTickFormatter(format="%14i")

    if tpf_source is not None:
        fig.rect('xx',
                 'yy',
                 1,
                 1,
                 source=tpf_source,
                 fill_color='gray',
                 fill_alpha=0.4,
                 line_color='white')

    # Configure the stretch slider and its callback function
    if scale == 'log':
        start, end = np.log10(vlo), np.log10(vhi)
        values = (np.log10(lo), np.log10(hi))
    elif scale == 'linear':
        start, end = vlo, vhi
        values = (lo, hi)

    stretch_slider = RangeSlider(start=start,
                                 end=end,
                                 step=vstep,
                                 title='Screen Stretch ({})'.format(scale),
                                 value=values,
                                 orientation='horizontal',
                                 width=200,
                                 direction='ltr',
                                 show_value=True,
                                 sizing_mode='fixed',
                                 height=15,
                                 name='tpfstretch')

    def stretch_change_callback_log(attr, old, new):
        """TPF stretch slider callback."""
        fig.select('tpfimg')[0].glyph.color_mapper.high = 10**new[1]
        fig.select('tpfimg')[0].glyph.color_mapper.low = 10**new[0]

    def stretch_change_callback_linear(attr, old, new):
        """TPF stretch slider callback."""
        fig.select('tpfimg')[0].glyph.color_mapper.high = new[1]
        fig.select('tpfimg')[0].glyph.color_mapper.low = new[0]

    if scale == 'log':
        stretch_slider.on_change('value', stretch_change_callback_log)
    if scale == 'linear':
        stretch_slider.on_change('value', stretch_change_callback_linear)

    return fig, stretch_slider
Example #30
0
def all_optics(out):
    """
    Maps of the wavelength dependent single scattering albedo 
    and cloud opacity and asymmetry parameter as a function of altitude. 

    Parameters
    ----------
    out : dict 
        Dictionary output from pyeddy run 

    Returns
    -------
    Three bokeh plots with the single scattering, optical depth, and assymetry maps
    """
    #get into DataFrame format
    dat01 = pyeddy.picaso_format(out['opd_per_layer'],
                      out['asymmetry'],out['single_scattering'])

    nwno=len(out['wave'])
    nlayer=len(out['pressure'])
    pressure=out['pressure']

    pressure_label = 'Pressure (Bars)'

    wavelength_label = 'Wavelength (um)'
    wavelength = out['wave']

    cols = colfun1(200)
    color_mapper = LinearColorMapper(palette=cols, low=0, high=1)

    #PLOT W0
    scat01 = np.flip(np.reshape(dat01['w0'].values,(nlayer,nwno)),0)
    xr, yr = scat01.shape
    f01a = figure(x_range=[0, yr], y_range=[0,xr],
                           x_axis_label=wavelength_label, y_axis_label=pressure_label,
                           title="Single Scattering Albedo",
                          plot_width=300, plot_height=300)


    f01a.image(image=[scat01],  color_mapper=color_mapper, x=0,y=0,dh=xr,dw =yr )

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

    f01a.add_layout(color_bar, 'left')


    #PLOT OPD
    scat01 = np.flip(np.reshape(dat01['opd'].values,(nlayer,nwno)),0)

    xr, yr = scat01.shape
    cols = colfun2(200)[::-1]
    color_mapper = LogColorMapper(palette=cols, low=1e-3, high=10)


    f01 = figure(x_range=[0, yr], y_range=[0,xr],
                           x_axis_label=wavelength_label, y_axis_label=pressure_label,
                           title="Cloud Optical Depth Per Layer",
                          plot_width=320, plot_height=300)

    f01.image(image=[scat01],  color_mapper=color_mapper, x=0,y=0,dh=xr,dw =yr )

    color_bar = ColorBar(color_mapper=color_mapper, ticker=LogTicker(),
                       label_standoff=12, border_line_color=None, location=(0,0))
    f01.add_layout(color_bar, 'left')

    #PLOT G0
    scat01 = np.flip(np.reshape(dat01['g0'].values,(nlayer,nwno)),0)

    xr, yr = scat01.shape
    cols = colfun3(200)[::-1]
    color_mapper = LinearColorMapper(palette=cols, low=0, high=1)


    f01b = figure(x_range=[0, yr], y_range=[0,xr],
                           x_axis_label=wavelength_label, y_axis_label=pressure_label,
                           title="Assymetry Parameter",
                          plot_width=300, plot_height=300)

    f01b.image(image=[scat01],  color_mapper=color_mapper, x=0,y=0,dh=xr,dw =yr )

    color_bar = ColorBar(color_mapper=color_mapper, ticker=BasicTicker(),
                       label_standoff=12, border_line_color=None, location=(0,0))
    f01b.add_layout(color_bar, 'left')

    #CHANGE X AND Y AXIS TO BE PHYSICAL UNITS 
    #indexes for pressure plot 
    if (pressure is not None):
        pressure = ["{:.1E}".format(i) for i in pressure[::-1]] #flip since we are also flipping matrices
        npres = len(pressure)
        ipres = np.array(range(npres))
        #set how many we actually want to put on the figure 
        #hard code ten on each.. 
        ipres = ipres[::int(npres/10)]
        pressure = pressure[::int(npres/10)]
        #create dictionary for tick marks 
        ptick = {int(i):j for i,j in zip(ipres,pressure)}
        for i in [f01a, f01, f01b]:
            i.yaxis.ticker = ipres
            i.yaxis.major_label_overrides = ptick
    if (wavelength is not None):
        wave = ["{:.2F}".format(i) for i in wavelength]
        nwave = len(wave)
        iwave = np.array(range(nwave))
        iwave = iwave[::int(nwave/10)]
        wave = wave[::int(nwave/10)]
        wtick = {int(i):j for i,j in zip(iwave,wave)}
        for i in [f01a, f01, f01b]:
            i.xaxis.ticker = iwave
            i.xaxis.major_label_overrides = wtick       

    return row(f01a, f01,f01b)