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')
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)
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
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
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
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") ]
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
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
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(),
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]])
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
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)
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')
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
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
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 }
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)")
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
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)
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)
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')
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
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)