def test_acceptance(validator: CompoundValidator): val = Marker(color='green', size=10) res = validator.validate_coerce(val) assert isinstance(res, Marker) assert res.color == 'green' assert res.size == 10
def plot_residuals(self, data, title): ''' Plots the residuals of the predicted values Parameters ========== data: pandas dataframe Dataframe that contains the actual (y) and predicted (y_pred) values. ''' data.iplot(data=[ dict(y=data['y'] - data['y_pred'], x=data['Dates'], name='Actual', mode='markers', marker=Marker(color='Black', size=3, opacity=1), color='Gray', showlegend=False), ], title=title, dimensions=(700, 400), vspan=dict(x0=datetime.datetime.strptime( self.testing_cutoff, "%Y%m%d"), x1=data['Dates'].max(), color='Black', width=0, fill=False, opacity=0.1))
def test_acceptance(validator): val = Marker(color="green", size=10) res = validator.validate_coerce(val) assert isinstance(res, Marker) assert res.color == "green" assert res.size == 10
def make_marker(obs, index): """ :param obs: Observation point containing 'value', 'index' and 'name' color: Same color as belonging line :returns: a marker for the value of the given observation. """ return Scatter(y=[obs['value']], x=[index], showlegend=False, mode='markers', marker=Marker(color='#000', ), hoverlabel=Hoverlabel(bgcolor='#000'))
def compare_portfolios(request): if request.method == "POST": portfolios = [] date_from = timezone.datetime(1999, 1, 1).date() for portfolio in Portfolio.objects.all(): if request.POST.get(str(portfolio.id)) is not None: portfolios.append(portfolio) delta = date_from - portfolio.creation_date if delta.days < 0: date_from = portfolio.creation_date stocks_list, min_create_date = get_all_tickers(portfolios), date_from download_stocks(stocks_list, min_create_date) R = [[ portfolio.name, PortfolioHandler(portfolio).getRByDates(date_from) ] for portfolio in portfolios] fig = go.Figure() for name, r in R: scatter = go.Scatter(x=r[0], y=r[1], mode='markers+lines', marker=Marker(symbol='0'), opacity=0.8, name=name) fig.add_trace(scatter) plt_div = plot(fig, output_type='div') return render( request, 'pages/compare.html', get_full_context( request, { 'page': COMPARE_PORTFOLIOS_PAGE_NAME, 'portfolios': Portfolio.objects.all(), 'html': plt_div })) return render( request, 'pages/compare.html', get_full_context( request, { 'page': COMPARE_PORTFOLIOS_PAGE_NAME, 'portfolios': Portfolio.objects.all(), }))
def plot_act_exp(self, data, title): ''' Plots the actuals vs the expected values Parameters ========== data: pandas dataframe Dataframe that contains the actual (y) and the predicted (y_pred) values with the standard deviation y_std ''' data.iplot(data=[ dict(y=data['y_pred'] - 1.96 * data['y_std'], x=data['Dates'], name='Predicted - 1.96 σ', line=Line(color='Gray', width=0), showlegend=False), dict(y=data['y_pred'] + 1.96 * data['y_std'], x=data['Dates'], name='Predicted + 1.96 σ', fill='tonexty', line=Line(color='Gray', width=0), showlegend=False), dict(y=data['y'], x=data['Dates'], name='Actual', mode='markers', marker=Marker(color='Black', size=3, opacity=1), color='Gray', showlegend=False), dict(y=data['y_pred'], x=data['Dates'], name='Predicted', line=Line(color='Blue', width=0.8), showlegend=False, opacity=0.5), ], title=title, dimensions=(700, 400), vspan=dict(x0=datetime.datetime.strptime( self.testing_cutoff, "%Y%m%d"), x1=data['Dates'].max(), color='Black', width=0, fill=False, opacity=0.1))
def get_single_propagation_scatter(self, color: Optional[str] = None) -> Scatter: time = defaultdict(int) for child in self.all_children: time[child.delay] += 1 x = sorted(time.keys()) y = [] for delay in x: prev_sum = y[-1] if y else 0 y.append(prev_sum + time[delay]) return Scatter(x=x, y=y, marker=Marker(color=color) if color else None, text=self.content)
def create_line_trace(net, lines=None, use_line_geodata=True, respect_switches=False, width=1.0, color='grey', infofunc=None, trace_name='lines', legendgroup=None, cmap=None, cbar_title=None, show_colorbar=True, cmap_vals=None, cmin=None, cmax=None, cpos=1.1): """ Creates a plotly trace of pandapower lines. INPUT: **net** (pandapowerNet) - The pandapower network OPTIONAL: **lines** (list, None) - The lines for which the collections are created. If None, all lines in the network are considered. **width** (int, 1) - line width **respect_switches** (bool, False) - flag for consideration of disconnected lines **infofunc** (pd.Series, None) - hoverinfo for line elements. Indices should correspond to the pandapower element indices **trace_name** (String, "lines") - name of the trace which will appear in the legend **color** (String, "grey") - color of lines in the trace **legendgroup** (String, None) - defines groups of layers that will be displayed in a legend e.g. groups according to voltage level (as used in `vlevel_plotly`) **cmap** (String, None) - name of a colormap which exists within plotly if set to True default `Jet` colormap is used, alternative colormaps : Greys, YlGnBu, Greens, YlOrRd, Bluered, RdBu, Reds, Blues, Picnic, Rainbow, Portland, Jet, Hot, Blackbody, Earth, Electric, Viridis **cmap_vals** (list, None) - values used for coloring using colormap **show_colorbar** (bool, False) - flag for showing or not corresponding colorbar **cbar_title** (String, None) - title for the colorbar **cmin** (float, None) - colorbar range minimum **cmax** (float, None) - colorbar range maximum **cpos** (float, 1.1) - position of the colorbar """ color = get_plotly_color(color) # defining lines to be plot lines = net.line.index.tolist() if lines is None else list(lines) if len(lines) == 0: return [] if infofunc is not None: if not isinstance(infofunc, pd.Series) and isinstance(infofunc, Iterable) and \ len(infofunc) == len(lines): infofunc = pd.Series(index=lines, data=infofunc) if len(infofunc) != len(lines) and len(infofunc) != len(net.line): raise UserWarning( "Different amount of hover info than lines to plot") assert isinstance(infofunc, pd.Series), \ "infofunc should be a pandas series with the net.line.index to the infofunc contents" no_go_lines = set() if respect_switches: no_go_lines = set(lines) & set(net.switch.element[ (net.switch.et == "l") & (net.switch.closed == 0)]) lines_to_plot = net.line.loc[set(net.line.index) & (set(lines) - no_go_lines)] no_go_lines_to_plot = None use_line_geodata = use_line_geodata if net.line_geodata.shape[ 0] > 0 else False if use_line_geodata: lines_to_plot = lines_to_plot.loc[set(lines_to_plot.index) & set(net.line_geodata.index)] else: lines_with_geodata = lines_to_plot.from_bus.isin(net.bus_geodata.index) & \ lines_to_plot.to_bus.isin(net.bus_geodata.index) lines_to_plot = lines_to_plot.loc[lines_with_geodata] cmap_lines = None if cmap is not None: # workaround: if colormap plot is used, each line need to be separate scatter object because # plotly still doesn't support appropriately colormap for line objects # TODO correct this when plotly solves existing github issue about Line colorbar cmap = 'jet' if cmap is True else cmap if cmap_vals is not None: if not isinstance(cmap_vals, np.ndarray): cmap_vals = np.asarray(cmap_vals) else: if net.res_line.shape[0] == 0: logger.error( "There are no power flow results for lines which are default for line colormap coloring..." "set cmap_vals input argument if you want colormap according to some specific values..." ) cmap_vals = net.res_line.loc[lines_to_plot.index, 'loading_percent'].values cmap_lines = get_plotly_cmap(cmap_vals, cmap_name=cmap, cmin=cmin, cmax=cmax) if len(cmap_lines) == len(net.line): # some lines are not plotted although cmap_value were provided for all lines line_idx_map = dict( zip(net.line.loc[lines].index.tolist(), range(len(lines)))) cmap_lines = [ cmap_lines[line_idx_map[idx]] for idx in lines_to_plot.index ] else: assert len(cmap_lines) == len(lines_to_plot), \ "Different amounts of cmap values and lines to plot were supplied" line_traces = [] for col_i, (idx, line) in enumerate(lines_to_plot.iterrows()): line_color = color line_info = line['name'] if cmap is not None: try: line_color = cmap_lines[col_i] line_info = line['name'] if infofunc is None else infofunc.loc[ idx] except IndexError: logger.warning( "No color and info for line {:d} (name: {}) available". format(idx, line['name'])) line_trace = dict(type='scatter', text=[], hoverinfo='text', mode='lines', name=trace_name, line=Line(width=width, color=color)) line_trace['x'], line_trace['y'] = _get_line_geodata_plotly( net, lines_to_plot.loc[idx:idx], use_line_geodata) line_trace['line']['color'] = line_color line_trace['text'] = line_info line_traces.append(line_trace) if show_colorbar and cmap is not None: cmin = cmap_vals.min() if cmin is None else cmin cmax = cmap_vals.max() if cmax is None else cmax try: # TODO for custom colormaps cbar_cmap_name = 'Jet' if cmap == 'jet' else cmap # workaround to get colorbar for lines (an unvisible node is added) # get x and y of first line.from_bus: x = [net.bus_geodata.x[net.line.from_bus[net.line.index[0]]]] y = [net.bus_geodata.y[net.line.from_bus[net.line.index[0]]]] lines_cbar = dict(type='scatter', x=x, y=y, mode='markers', marker=Marker( size=0, cmin=cmin, cmax=cmax, color='rgb(255,255,255)', opacity=0, colorscale=cbar_cmap_name, colorbar=ColorBar(thickness=10, x=cpos), )) if cbar_title: lines_cbar['marker']['colorbar']['title'] = cbar_title lines_cbar['marker']['colorbar']['title']['side'] = 'right' line_traces.append(lines_cbar) except: pass if len(no_go_lines) > 0: no_go_lines_to_plot = net.line.loc[no_go_lines] for idx, line in no_go_lines_to_plot.iterrows(): line_color = color line_trace = dict(type='scatter', text=[], hoverinfo='text', mode='lines', name='disconnected lines', line=Line(width=width / 2, color='grey', dash='dot')) line_trace['x'], line_trace['y'] = _get_line_geodata_plotly( net, no_go_lines_to_plot.loc[idx:idx], use_line_geodata) line_trace['line']['color'] = line_color try: line_trace['text'] = infofunc.loc[idx] except (KeyError, IndexError, AttributeError): line_trace["text"] = line['name'] line_traces.append(line_trace) if legendgroup: line_trace['legendgroup'] = legendgroup # sort infofunc so that it is the correct order lines_to_plot + no_go_lines_to_plot if infofunc is not None: if not isinstance(infofunc, pd.Series) and isinstance(infofunc, Iterable) and \ len(infofunc) == len(net.line): infofunc = pd.Series(index=net.line.index, data=infofunc) assert isinstance(infofunc, pd.Series), \ "infofunc should be a pandas series with the net.line.index to the infofunc contents" sorted_idx = lines_to_plot.index.tolist() if no_go_lines_to_plot is not None: sorted_idx += no_go_lines_to_plot.index.tolist() infofunc = infofunc.loc[sorted_idx] center_trace = create_edge_center_trace(line_traces, color=color, infofunc=infofunc, use_line_geodata=use_line_geodata) line_traces.append(center_trace) return line_traces
def create_bus_trace(net, buses=None, size=5, patch_type="circle", color="blue", infofunc=None, trace_name='buses', legendgroup=None, cmap=None, cmap_vals=None, cbar_title=None, cmin=None, cmax=None, cpos=1.0, colormap_column="vm_pu"): """ Creates a plotly trace of pandapower buses. INPUT: **net** (pandapowerNet) - The pandapower network OPTIONAL: **buses** (list, None) - The buses for which the collections are created. If None, all buses in the network are considered. **size** (int, 5) - patch size **patch_type** (str, "circle") - patch type, can be - "circle" for a circle - "square" for a rectangle - "diamond" for a diamond - much more pathc types at https://plot.ly/python/reference/#scatter-marker **infofunc** (pd.Series, None) - hoverinfo for bus elements. Indices should correspond to the pandapower element indices **trace_name** (String, "buses") - name of the trace which will appear in the legend **color** (String, "blue") - color of buses in the trace **cmap** (String, None) - name of a colormap which exists within plotly (Greys, YlGnBu, Greens, YlOrRd, Bluered, RdBu, Reds, Blues, Picnic, Rainbow, Portland, Jet, Hot, Blackbody, Earth, Electric, Viridis) alternatively a custom discrete colormap can be used **cmap_vals** (list, None) - values used for coloring using colormap **cbar_title** (String, None) - title for the colorbar **cmin** (float, None) - colorbar range minimum **cmax** (float, None) - colorbar range maximum **cpos** (float, 1.1) - position of the colorbar **colormap_column** (str, "vm_pu") - set color of bus according to this variable """ color = get_plotly_color(color) bus_trace = dict(type='scatter', text=[], mode='markers', hoverinfo='text', name=trace_name, marker=dict(color=color, size=size, symbol=patch_type)) buses = net.bus.index.tolist() if buses is None else list(buses) bus_plot_index = [ b for b in buses if b in list(set(buses) & set(net.bus_geodata.index)) ] bus_trace['x'], bus_trace['y'] = (net.bus_geodata.loc[bus_plot_index, 'x'].tolist(), net.bus_geodata.loc[bus_plot_index, 'y'].tolist()) if not isinstance(infofunc, pd.Series) and isinstance(infofunc, Iterable) and \ len(infofunc) == len(buses): infofunc = pd.Series(index=buses, data=infofunc) bus_trace['text'] = net.bus.loc[bus_plot_index, 'name'] if infofunc is None else \ infofunc.loc[buses] if legendgroup: bus_trace['legendgroup'] = legendgroup # if color map is set if cmap is not None: # TODO introduce discrete colormaps (see contour plots in plotly) # if cmap_vals are not given cmap = 'Jet' if cmap is True else cmap if cmap_vals is not None: cmap_vals = cmap_vals else: if net.res_line.shape[0] == 0: logger.error( "There are no power flow results for buses voltage magnitudes which are default for bus " "colormap coloring..." "set cmap_vals input argument if you want colormap according to some specific values..." ) cmap_vals = net.res_bus.loc[bus_plot_index, colormap_column].values cmap_vals = net.res_bus.loc[ bus_plot_index, colormap_column] if cmap_vals is None else cmap_vals cmin = cmap_vals.min() if cmin is None else cmin cmax = cmap_vals.max() if cmax is None else cmax bus_trace['marker'] = Marker(size=size, color=cmap_vals, cmin=cmin, cmax=cmax, colorscale=cmap, colorbar=ColorBar(thickness=10, x=cpos), symbol=patch_type) if cbar_title: bus_trace['marker']['colorbar']['title'] = cbar_title bus_trace['marker']['colorbar']['title']['side'] = 'right' return [bus_trace]
def _create_branch_trace(net, branches=None, use_branch_geodata=True, respect_separators=False, width=1.0, color='grey', infofunc=None, trace_name='lines', legendgroup=None, cmap=None, cbar_title=None, show_colorbar=True, cmap_vals=None, cmin=None, cmax=None, cpos=1.1, branch_element='line', separator_element='switch', node_element='bus', cmap_vals_category='loading_percent'): """ Creates a plotly trace of branch elements. The rather generic, non-power net specific names were introduced to make it usable in other packages, e.g. for pipe networks. INPUT: **net** (pandapowerNet) - The network OPTIONAL: **branches** (list, None) - The branches for which the collections are created. If None, all branches in the network are considered. **use_branch_geodata** (bool, True) - whether the geodata of the branch tables should be used **respect_separators** (bool, True) - whether separating elements like switches should be considered **width** (int, 1) - branch width **color** (String, "grey") - color of lines in the trace **infofunc** (pd.Series, None) - hoverinfo for line elements. Indices should correspond to the pandapower element indices **trace_name** (String, "lines") - name of the trace which will appear in the legend **legendgroup** (String, None) - defines groups of layers that will be displayed in a legend e.g. groups according to voltage level (as used in `vlevel_plotly`) **cmap** (String, None) - name of a colormap which exists within plotly if set to True default `Jet` colormap is used, alternative colormaps : Greys, YlGnBu, Greens, YlOrRd, Bluered, RdBu, Reds, Blues, Picnic, Rainbow, Portland, Jet, Hot, Blackbody, Earth, Electric, Viridis **cmap_vals** (list, None) - values used for coloring using colormap **show_colorbar** (bool, False) - flag for showing or not corresponding colorbar **cbar_title** (String, None) - title for the colorbar **cmin** (float, None) - colorbar range minimum **cmax** (float, None) - colorbar range maximum **cpos** (float, 1.1) - position of the colorbar **branch_element** (str, "line") - name of the branch element in the net. In a pandapower net, this is alwas "line" **separator_element** (str, "switch") - name of the separator element in the net. In a pandapower net, this is alwas "switch" **node_element** (str, "bus") - name of the node element in the net. In a pandapower net, this is alwas "bus" (net.bus) """ color = get_plotly_color(color) # defining branches (lines) to be plot branches = net[branch_element].index.tolist( ) if branches is None else list(branches) if len(branches) == 0: return [] if infofunc is not None: if not isinstance(infofunc, pd.Series) and isinstance(infofunc, Iterable) and \ len(infofunc) == len(branches): infofunc = pd.Series(index=branches, data=infofunc) if len(infofunc) != len(branches) and len(infofunc) != len( net[branch_element]): raise UserWarning("Different amount of hover info than {}s to " "plot".format(branch_element)) assert isinstance(infofunc, pd.Series), \ "infofunc should be a pandas series with the net.{}.index to the infofunc " \ "contents".format(branch_element) no_go_branches = set() if respect_separators: if separator_element == "switch": no_go_branches = set(branches) & \ set(net[separator_element].element[(net[separator_element].et == "l") & (net[separator_element].closed == 0)]) elif separator_element == "valve": no_go_branches = set(branches) & \ set(net[separator_element][(~net[separator_element].in_service) | (net[separator_element].opened)]) else: raise NotImplementedError( "respect separtors is only implements for switches, " "not for {}s.".format(separator_element)) branches_to_plot = net[branch_element].loc[set(net[branch_element].index) & (set(branches) - no_go_branches)] no_go_branches_to_plot = None branch_geodata = branch_element + "_geodata" node_geodata = node_element + "_geodata" use_branch_geodata = use_branch_geodata if net[branch_geodata].shape[ 0] > 0 else False if use_branch_geodata: branches_to_plot = branches_to_plot.loc[ set(branches_to_plot.index) & set(net[branch_geodata].index)] else: branches_with_geodata = branches_to_plot['from_'+node_element].isin( net[node_geodata].index) & \ branches_to_plot['to_'+node_element].isin(net[node_geodata].index) branches_to_plot = branches_to_plot.loc[branches_with_geodata] cmap_branches = None if cmap is not None: # workaround: if colormap plot is used, each line need to be separate scatter object because # plotly still doesn't support appropriately colormap for line objects # TODO correct this when plotly solves existing github issue about Line colorbar cmap = 'jet' if cmap is True else cmap if cmap_vals is not None: if not isinstance(cmap_vals, np.ndarray): cmap_vals = np.asarray(cmap_vals) else: if net['res_' + branch_element].shape[0] == 0: logger.error( "There are no simulation results for branches which are default for {}" "colormap coloring..." "set cmap_vals input argument if you want colormap according to some specific " "values...".format(branch_element)) cmap_vals = net['res_' + branch_element].loc[branches_to_plot.index, cmap_vals_category].values cmap_branches = get_plotly_cmap(cmap_vals, cmap_name=cmap, cmin=cmin, cmax=cmax) if len(cmap_branches) == len(net[branch_element]): # some branches are not plotted although cmap_value were provided for all branches branch_idx_map = dict( zip(net[branch_element].loc[branches].index.tolist(), range(len(branches)))) cmap_branches = [ cmap_branches[branch_idx_map[idx]] for idx in branches_to_plot.index ] else: assert len(cmap_branches) == len(branches_to_plot), \ "Different amounts of cmap values and branches to plot were supplied" branch_traces = [] for col_i, (idx, branch) in enumerate(branches_to_plot.iterrows()): line_color = color line_info = branch['name'] if cmap is not None: try: line_color = cmap_branches[col_i] line_info = branch[ 'name'] if infofunc is None else infofunc.loc[idx] except IndexError: logger.warning( "No color and info for {} {:d} (name: {}) available". format(branch_element, idx, branch['name'])) line_trace = dict(type='scatter', text=[], hoverinfo='text', mode='lines', name=trace_name, line=Line(width=width, color=color)) line_trace['x'], line_trace['y'] = _get_branch_geodata_plotly( net, branches_to_plot.loc[idx:idx], use_branch_geodata, branch_element, node_element) line_trace['line']['color'] = line_color line_trace['text'] = line_info branch_traces.append(line_trace) if show_colorbar and cmap is not None: cmin = cmap_vals.min() if cmin is None else cmin cmax = cmap_vals.max() if cmax is None else cmax try: # TODO for custom colormaps cbar_cmap_name = 'Jet' if cmap == 'jet' else cmap # workaround to get colorbar for branches (an unvisible node is added) # get x and y of first line.from_bus: x = [ net[node_geodata].x[net[branch_element]["from_" + node_element] [net[branch_element].index[0]]] ] y = [ net[node_geodata].y[net[branch_element]["from_" + node_element] [net[branch_element].index[0]]] ] branches_cbar = dict(type='scatter', x=x, y=y, mode='markers', marker=Marker( size=0, cmin=cmin, cmax=cmax, color='rgb(255,255,255)', opacity=0, colorscale=cbar_cmap_name, colorbar=ColorBar(thickness=10, x=cpos), )) if cbar_title: branches_cbar['marker']['colorbar']['title'] = cbar_title branches_cbar['marker']['colorbar']['title']['side'] = 'right' branch_traces.append(branches_cbar) except: pass if len(no_go_branches) > 0: no_go_branches_to_plot = net[branch_element].loc[no_go_branches] for idx, branch in no_go_branches_to_plot.iterrows(): line_color = color line_trace = dict(type='scatter', text=[], hoverinfo='text', mode='lines', name='disconnected branches', line=Line(width=width / 2, color='grey', dash='dot')) line_trace['x'], line_trace['y'] = _get_branch_geodata_plotly( net, no_go_branches_to_plot.loc[idx:idx], use_branch_geodata, branch_element, node_element) line_trace['line']['color'] = line_color try: line_trace['text'] = infofunc.loc[idx] except (KeyError, IndexError, AttributeError): line_trace["text"] = branch['name'] branch_traces.append(line_trace) if legendgroup: line_trace['legendgroup'] = legendgroup # sort infofunc so that it is the correct order lines_to_plot + no_go_lines_to_plot if infofunc is not None: if not isinstance(infofunc, pd.Series) and isinstance(infofunc, Iterable) and \ len(infofunc) == len(net[branch_element]): infofunc = pd.Series(index=net[branch_element].index, data=infofunc) assert isinstance(infofunc, pd.Series), \ "infofunc should be a pandas series with the net.{}.index to the infofunc contents" \ .format(branch_element) sorted_idx = branches_to_plot.index.tolist() if no_go_branches_to_plot is not None: sorted_idx += no_go_branches_to_plot.index.tolist() infofunc = infofunc.loc[sorted_idx] center_trace = create_edge_center_trace( branch_traces, color=color, infofunc=infofunc, use_line_geodata=use_branch_geodata) branch_traces.append(center_trace) return branch_traces
def offline_plotly_scatter_bubble( df, x='x', y='y', size_col='size', text_col='text', category_col='category', possible_categories=None, filename=None, config={'displaylogo': False}, xscale=None, yscale='log', layout={ 'hovermode': 'closest', 'showlegend': False, 'autosize': True }, marker={'sizemode': 'area'}, min_size=10, ): r"""Interactive scatterplot of a DataFrame with the size and color of circles linke to two columns config keys: fillFrame setBackground displaylogo sendData showLink linkText staticPlot scrollZoom plot3dPixelRatio displayModeBar showTips workspace doubleClick autosizable editable layout keys: angularaxis annotations autosize bargap bargroupgap barmode barnorm boxgap boxgroupgap boxmode calendar direction dragmode font geo height hiddenlabels hiddenlabelssrc hidesources hovermode images legend mapbox margin orientation paper_bgcolor plot_bgcolor radialaxis scene separators shapes showlegend sliders smith ternary title titlefont updatemenus width xaxis yaxis marker keys: autocolorscale blend border cauto cmax cmin color colorbar colors colorscale colorsrc colorssrc line maxdisplayed opacity opacitysrc outliercolor reversescale showscale size sizemax sizemin sizemode sizeref sizesrc symbol symbolsrc marker['sizeref'] gives the denominator of the circle scaling factor. Typically it should be about a tenth of the minimum 'size' column value >>> from nlpia.data.loaders import get_data >>> df = get_data('cities_us_wordvectors_pca2_meta').iloc[:100] >>> html = offline_plotly_scatter_bubble( ... df.sort_values('population', ascending=False)[:350].copy().sort_values('population'), ... x='x', y='y', ... size_col='population', text_col='name', category_col='timezone', ... xscale=None, yscale=None, # 'log' or None ... layout={}, marker={'sizeref': 3000}) """ config_default = dict(DEFAULT_PLOTLY_CONFIG) marker_default = { 'size': size_col or min_size, 'sizemode': 'area', 'sizeref': int(df[size_col].min() * .8) if size_col else min_size } marker_default.update(marker) size_col = marker_default.pop('size') layout_default = { 'xaxis': XAxis(title=x, type=xscale), 'yaxis': YAxis(title=y, type=yscale), } layout_default.update(**layout) if config is not None: config_default.update(config) df.columns = clean_columns(df.columns) if possible_categories is None and category_col is not None: if category_col in df.columns: category_labels = df[category_col] else: category_labels = np.array(category_col) possible_categories = list(set(category_labels)) possible_categories = [ None ] if possible_categories is None else possible_categories if category_col and category_col in df: masks = [ np.array(df[category_col] == label) for label in possible_categories ] else: masks = [np.array([True] * len(df))] * len(possible_categories) data = { 'data': [ Scatter(x=df[x][mask].values, y=df[y][mask].values, text=df[text_col][mask].values, marker=Marker(size=df[size_col][mask] if size_col in df.columns else size_col, **marker_default), mode='markers', name=str(category_name)) for (category_name, mask) in zip(possible_categories, masks) ], 'layout': Layout(**layout_default) } return offline_plotly_data(data, filename=filename, config=config_default)
def make_graph(nodes: list, edges: list): """ Creates plotly network graph. Parameters ---------- nodes: list of nodes compatible with networx edges: list of edges compatible with networx Returns ------- plotly.graph_objs.Figure """ G = nx.Graph() # Create graph G.add_nodes_from(nodes) G.add_edges_from(edges) # Hack edge_labels_x = [] edge_labels_y = [] edge_labels_txt = [] # Define appends for better performance add_x = edge_labels_x.append add_y = edge_labels_y.append add_txt = edge_labels_txt.append # Create edges plot edge_traces = [] add = edge_traces.append for edge in G.edges(data=True): a, b, info = edge x0, y0 = G.node[a]['pos'] x1, y1 = G.node[b]['pos'] trace = go.Scatter(x=[x0, x1, None], y=[y0, y1, None], line=_color_edge(info), hoverinfo='none', mode='lines') add(trace) add_x((x0 + x1) / 2) add_y((y0 + y1) / 2) add_txt(f"time: {info['time'] }") # Hack for info hover on edges: middle_node_trace = go.Scatter(x=edge_labels_x, y=edge_labels_y, text=edge_labels_txt, mode='markers', hoverinfo='text', marker=Marker(opacity=0)) node_trace = go.Scatter(x=[], y=[], text=[], mode='markers', hoverinfo='text', marker=Marker(color=[], size=10, line=dict(width=2))) # Create nodes plot for node in G.nodes(): the_node = G.node[node] x, y = the_node['pos'] node_trace['x'] += tuple([x]) node_trace['y'] += tuple([y]) node_info = reduce(lambda a, b: f'{a} | {b}', [f'{k} : {v}' for k, v in the_node.items()]) node_trace['text'] += tuple([node_info]) data = edge_traces + [node_trace, middle_node_trace] return go.Figure(data=data, layout=go.Layout( showlegend=False, hovermode='closest', margin=dict(b=20, l=5, r=5, t=40), annotations=[ dict(text='', showarrow=False, xref="paper", yref="paper", x=0.005, y=-0.002) ], xaxis=dict(showgrid=False, zeroline=False, showticklabels=False), yaxis=dict(showgrid=False, zeroline=False, showticklabels=False, scaleanchor="x", scaleratio=1), ))