def _add_tier_annotations(fig: go.Figure) -> go.Figure: """Adds tier annotations to the figure.""" fig.add_traces([ go.Scatter(x=[x_, x_], y=[-2, 40], line_color="gray", line_dash="dash") for x_ in [1.5, 1, 0.5] ]) annos = [ (1.75, 10, "S TIER"), (1.25, 10, "A TIER"), (0.75, 10, "B TIER"), (0.25, 10, "C TIER"), ] for anno in annos: annotation = dict( x=anno[0], y=anno[1], text="<b>%s</b>" % anno[2], showarrow= True, # with True there is no arrow, but text is centered xanchor="left", yanchor="middle", borderpad=0, font=dict(color="black", size=50, family="MonacoRegular"), opacity=0.7, textangle=90, ) fig.add_annotation(annotation) return fig
def _save(self, data: go.Figure) -> None: save_path = get_filepath_str(self._get_save_path(), self._protocol) with self._fs.open(save_path, **self._fs_open_args_save) as fs_file: data.write_json(fs_file, **self._save_args) self._invalidate_cache()
def plot(self, fig: go.Figure) -> go.Figure: width = 2 color1 = 'rgba(46, 134, 193, 0.5)' color2 = 'rgba(40, 180, 99, 0.5)' color3 = 'rgba(136, 78, 160, 0.5)' position = (1, 1) macd_, signal, hist = self.result #fig.add_trace(go.Scatter(x=self.data['date'], # y=macd_, # mode='lines', # name='macd', # line=dict(color=color1, width=width) # ), # row=position[0], col=position[1] # ) fig.add_trace(go.Scatter(x=self.data['date'], y=signal, mode='lines', name='macd_signal', line=dict(color=color2, width=width)), row=position[0], col=position[1]) fig.add_trace(go.Bar( x=self.data['date'], y=hist, marker_color=color3, name='macd_hist', ), row=position[0], col=position[1]) return fig
def run_and_plot_single_fit_comparison(fig: go.Figure, data: Data1D) -> go.Figure: """ Runs both Args: fig (): data (): Returns: """ i_sense_fit = fit_single_transition(data, fit_with='i_sense', initial_params=None) nrg_params = get_initial_params(data, 'nrg') nrg_params['g'].value = 0.001 nrg_params['g'].vary = False nrg_params['occ_lin'].vary = False nrg_fit = fit_single_transition(data, fit_with='nrg', initial_params=nrg_params) for fit, name in zip([i_sense_fit, nrg_fit], ['i_sense', 'NRG']): fig.add_trace( p1d.trace(x=data.x, data=fit.eval_fit(x=data.x), name=name, mode='lines')) print(i_sense_fit) print(nrg_fit) return fig
def show_plot(fig: go.Figure) -> None: """Save plot to the specified file.""" # Show only if SHOW_PLOT is True if SHOW_PLOT: fig.update_layout(template=_plot_layout_template) fig.show()
def plot_traces(self, fig: go.Figure, data: pd.DataFrame, x: str, y: str, hue: str, row: int, col: int, mode: str = 'lines') -> go.Figure: """ The goal is create a similar behavior as plotly express or seaborn. This function will take x, y, and hue column names and use them to layer the correct scatter plots together. :param fig: ploty fig where this plot (or these traces) will be places :param data: dataframe containing all the columns listed in x, y, and hue :param x: column name of x-axis :param y: column name of y-axis :param hue: column name of category column :param row: the row number inside the fig where the plot will be located :param col: the column number inside the fig where the plot :param mode: plotly.graph_objects.Scatter mode value :return: plot fig with plot added s """ for n, category in enumerate(data[hue].unique()): temp = data[data[hue] == category] chart = go.Scatter(x=temp[x], y=temp[y], mode='lines', name=category, marker_color=px.colors.sequential.Plasma[n]) fig.add_trace(chart, row=row, col=col) return fig
def update_layout(df: pd.DataFrame, fig: go.Figure) -> None: fig.update_layout( xaxis={ 'tickvals': df['date'], 'tickformat': DATE_FORMAT, 'tickangle': 45, 'type': 'date', 'ticks': 'outside', 'ticklen': 5, 'tickwidth': 2, 'showline': True, 'linewidth': 2, 'linecolor': 'black', 'tickfont': { 'size': 14 }, }, yaxis={ 'showgrid': True, 'gridwidth': 0.5, 'gridcolor': GRID_COLOR, 'ticks': 'outside', 'ticklen': 5, 'tickwidth': 2, 'showline': True, 'linewidth': 2, 'linecolor': 'black', #'dtick': 20, 'tickfont': { 'size': 14 }, }, plot_bgcolor="white", )
def __add_const_trend_trace(self, trend_name: str, trend: PlotlyTrendLine, fig: pgo.Figure): all_series = {**self.series, **self.averages} if trend.related_series_id not in all_series: raise InvalidTrendLine(f"Missing related series: {trend.related_series_id}") if trend.constant is None: raise InvalidTrendLine(f"Constant must be specified to draw const trendline") series = all_series[trend.related_series_id] xs_range = series.data[series.x_field] xs = np.linspace(xs_range.min(), xs_range.max(), 10) ys = np.full(10, trend.constant) trace = pgo.Scatter( x=xs, y=ys, name=trend_name, mode='lines', line={ 'dash': 'dash', 'color': 'red', 'width': 0.4, } ) fig.add_trace(trace)
def init_figure(self, analyzed_interval, predictions, model): """ Initializes the plotly Figure and puts predictions argument as candlestick data into the chart Parameters: analyzed_interval : np.ndarray - dates and prices predictions : np.ndarray - hardmax indices of model's predictions model : keras.Model Returns: figure : plotly.Figure """ candlestick = Candlestick(x=analyzed_interval[:, 0], open=analyzed_interval[:, 1], high=analyzed_interval[:, 2], low=analyzed_interval[:, 3], close=analyzed_interval[:, 4]) figure = Figure(data=[candlestick]) model.categories.sort() steps = ', '.join(['+' + str(c) + '%' for c in model.categories]) title = ('Predictions of ' + model.name + ' for the next ' + str(model.prediction_interval) + ' days based on the previous ' + str(model.input_interval) + ' days. Steps: ' + steps) figure.update_layout(title=title, yaxis_title='Price') return figure
def add_textbox(fig: go.Figure, text: str, position: Union[str, Tuple[float, float]], fontsize=10) -> None: """ Adds <text> to figure in a text box. Args: fig (): Figure to add text box to text (): Text to add position (): Absolute position on figure to add to (e.g. (0.5,0.9) for center top, or 'CT' for center top, or 'T' for center top) Returns: None: Modifies figure passed in """ if isinstance(position, str): position = get_position_from_string(position) text = text.replace('\n', '<br>') fig.add_annotation(text=text, xref='paper', yref='paper', x=position[0], y=position[1], showarrow=False, bordercolor='#111111', borderpad=3, borderwidth=1, opacity=0.8, bgcolor='#F5F5F5', font=dict(size=fontsize))
def update_axes(fig: Figure, temp_kwargs: Dict[str, Any]) -> None: """ Separeated this portion of the code because it is clumsy. It changes the axes looks. """ # Layout and title parameters https://plotly.com/python/figure-labels/ fig.update_layout(scene=dict( xaxis=dict( title_text=temp_kwargs['x_label'], showline=True, linewidth=2, linecolor='black', ticks="outside", mirror=True, backgroundcolor='#9467bd', ), yaxis=dict( title_text=temp_kwargs['y_label'], showline=True, linewidth=2, linecolor='black', ticks="outside", mirror=True, backgroundcolor='#9467bd', ), zaxis=dict( title_text=temp_kwargs['z_label'], showline=True, linewidth=2, linecolor='black', ticks="outside", mirror=True, backgroundcolor='#9467bd', #change the color of axis )))
def save_figure(fig: go.Figure, dformat: str, output_path: str): if dformat == 'html': fig.write_html(output_path) elif dformat in SUPPORTED_FORMATS: fig.write_image(output_path, format=dformat) else: raise NotImplemented(f'Format {dformat} is not supported')
def show(self, *args, **kwargs) -> None: """Show the figure.""" from vectorbt.settings import plotting fig_kwargs = dict(width=self.layout.width, height=self.layout.height) show_kwargs = merge_dicts(fig_kwargs, plotting['show'], kwargs) _Figure.show(self, *args, **show_kwargs)
def wrap_plotly_fig(fig: go.Figure, width: str = '100%', height: str = '100%'): if 'px' in width: fig = fig.to_html(include_plotlyjs=False, full_html=False, default_height=height, default_width=width) return div(raw(fig), style=f'width: {width}') else: fig = fig.to_html(include_plotlyjs=False, full_html=False, default_height=height, default_width='100%') return div(raw(fig), style=f'width: {width}')
def add_area_trace( fig: go.Figure, x_series: list, y_series: list, name: str, color: str, row: int, showlegend: bool = True, linewidth: float = 0.2, ) -> go.Figure: """Adding single area trace to subplot""" fig.add_trace( go.Scatter( x=x_series, y=y_series, hoverinfo="text+x+y", hoveron="fills", mode="lines", # fill="tonexty", # fillcolor=color, line=dict(width=linewidth, color=color), name=name, text=name, stackgroup="one", legendgroup="Ctrl Modes", showlegend=showlegend, ), row=row, col=1, )
def main(): # Data File Name and file path filename = 'us-counties.csv' filepath = os.path.join('./data/raw', filename) # Import data into DataFrame and rename columns df = read_csv(filepath, dtype={'fips': str}) df.columns = ['date', 'county', 'state', 'zip', 'cases', 'deaths'] print(df.dtypes) print(f'Number of total cases: {df.cases.sum()}') print(f'Number of total deaths: {df.deaths.sum()}') # Extract Year, Month and Date and place in separate columns df['year'] = DatetimeIndex(df.date, yearfirst=True).year df['month'] = DatetimeIndex(df.date, yearfirst=True).month_name() # States and Counties states = df.state.unique() counties = df.county.unique() # Sum of Grouped Dats grp_dates = df.groupby(['date', 'state'])['cases', 'deaths'].sum() print(grp_dates.sum()) # Plot Scatter plot of Cases vs Deaths renderers.default = 'browser' fig = Figure(data=Scatter(x=df.cases, y=df.deaths, mode='markers')) fig.show() return
def __add_trace(self, series: PlotSeries, fig: pgo.Figure): show_error_y = self.properties.show_error_bars and \ series.y_err_field is not None and \ series.y_err_field in series.data.columns trace_mode = { PlotSeriesKind.SCATTER: 'markers', PlotSeriesKind.SCATTERLINE: 'markers+lines', PlotSeriesKind.LINE: 'lines', }[self.properties.default_series_kind] trace = pgo.Scatter( name=series.series_info.series_name, mode=trace_mode, x=series.data[series.x_field], y=series.data[series.y_field], error_y=None if not show_error_y else { 'type': 'data', 'visible': series.y_err_field is not None, 'array': series.data[series.y_err_field], 'color': PlotUtils.series_color_hex(series.series_info.series_id), 'thickness': 0.5, 'width': 1, }, marker={ 'symbol': 'circle', }, line={ 'color': PlotUtils.series_color_hex(series.series_info.series_id), } ) fig.add_trace(trace)
def generate_line_plots( y_matrix: np.ndarray, lap_time_matrix: np.ndarray, figure: go.Figure, ) -> None: """ Given a matrix of lap times and a matrix to plot on the y-axis, this function will add line plots to the figure. Each line could represent, e.g., the distance to the first driver or the position of the driver Parameters ---------- y_matrix Each row of this matrix will become a separate line in the figure lap_time_matrix A matrix with the lap times for each driver figure The figure to which the lines should be added Returns ------- """ for driver_idx in range(lap_time_matrix.shape[0]): line_plot = go.Scatter( x=list(range(lap_time_matrix.shape[1])), y=y_matrix[driver_idx, :], name=f'Driver {driver_idx}', marker_size=1, ) figure.add_trace(line_plot)
def __add_ml_linear_trend_trace(self, trend_name: str, trend: PlotlyTrendLine, fig: pgo.Figure): all_series = {**self.series, **self.averages} if trend.related_series_id not in all_series: raise InvalidTrendLine(f"Missing related series: {trend.related_series_id}") series = all_series[trend.related_series_id] xs = np.array(series.data[series.x_field]).reshape(-1, 1) ys = np.array(series.data[series.y_field]).reshape(-1, 1) model = LinearRegression() model.fit(xs, ys) xs_predict = np.linspace(xs.min(), xs.max(), 100).reshape(-1, 1) ys_predict = model.predict(xs_predict) trace = pgo.Scatter( x=xs_predict.reshape(1, -1)[0], y=ys_predict.reshape(1, -1)[0], name=trend_name, mode='lines', line={ 'dash': 'dash', 'color': 'red', } ) fig.add_trace(trace)
def _fig_layout(fig: go.Figure) -> go.Figure: """ Modify the figure to match the desired style :param fig: figure to be formatted :return: formatted figure """ fig.update_layout(xaxis=dict( showline=True, showgrid=False, showticklabels=True, linecolor='rgb(204, 204, 204)', linewidth=2, ticks='outside', tickfont=dict( family='Arial', size=12, color='rgb(82, 82, 82)', ), ), yaxis=dict( showgrid=False, zeroline=False, showline=False, showticklabels=False, ), autosize=True, showlegend=False, margin=dict( autoexpand=False, l=20, r=20, t=110, ), plot_bgcolor='white') return fig
def plot_3d(self): z = self.get_point_clouds() fig = Figure(data=Scatter3d(x=z[:,0].ravel(), y=z[:,1].ravel(), z=z[:,2].ravel(), mode='markers', marker=dict(size=1) ) ) x_range = [floor(z[:,0].min()), ceil(z[:,0].max())] y_range = [floor(z[:,1].min()), ceil(z[:,1].max())] z_range = [floor(z[:,2].min()), ceil(z[:,2].max())] x_len = x_range[1] - x_range[0] y_len = y_range[1] - y_range[0] z_len = z_range[1] - z_range[0] base = min([x_len, y_len, z_len]) fig.update_layout( scene = dict( aspectmode='manual', aspectratio=dict(x=x_len/base, y=y_len/base, z=z_len/base), xaxis = dict(range=x_range), yaxis = dict(range=y_range), zaxis = dict(range=z_range) ) ) return fig
def format_well_overview_figure(figure: go.Figure, charttype: str, settings: List[str], sumvec: str) -> go.Figure: """This function formate the well overview figure. The reason for keeping this function outside the figure class is that we can update the figure formatting without generating a new WellOverviewFigure object and reloading the data. It can be applied directly to the current state of the figure dict if only formatting settings are changed. See in the well_overview_callbacks how it is used. """ if charttype == "pie": figure.update_traces( texttemplate=("%{label}<br>%{value:.2s}" if "show_prod_text" in settings else "%{label}")) elif charttype == "bar": figure.update_layout( barmode=("overlay" if "overlay_bars" in settings else "group")) figure.update_traces( textposition=("auto" if "show_prod_text" in settings else "none")) # These are valid for all chart types figure.update_layout(template=( "plotly_white" if "white_background" in settings else "plotly")) phase = {"WOPT": "Oil", "WGPT": "Gas", "WWPT": "Water"}[sumvec] figure.update( layout_title_text=f"Cumulative Well {phase} Production (Sm3)", layout_showlegend=("legend" in settings), ) return figure
def add_periodic_vertical_lines(fig: go.Figure, start: Union[str, Timestamp], end: Union[str, Timestamp], freq: str, y1: float, y0: float = 0) -> go.Figure: """ add vertical lines to plotly figures that repeat at a certain frequency ie every sunday Args: fig: plotly figure start: first date of period end: last date of the period freq: pandas time series frequency directive ie W-THU y1: max value of line y0: minimum value of line Returns: fig: the plotly figures with lines added as a trace """ dates_dow = pd.date_range(start, end, freq=freq) for day in dates_dow: fig.add_shape( type='line', x0=day, y0=y0, x1=day, y1=y1, line=dict(width=1, dash='dot'), ) return fig
def update_layout(fig: go.Figure) -> None: fig.update_layout( xaxis={ 'tick0': 0, 'dtick': 20, 'ticks': 'outside', 'ticklen': 5, 'tickwidth': 2, 'tickangle': 45, 'tickfont': {'size': 14}, 'showline': True, 'linewidth': 2, 'linecolor': 'black', }, yaxis={ 'showgrid': True, 'gridwidth': 0.5, 'gridcolor': GRID_COLOR, 'ticks': 'outside', 'ticklen': 5, 'tickwidth': 2, 'tickfont': {'size': 14}, 'showline': True, 'linewidth': 2, 'linecolor': 'black', 'tick0': 0, 'dtick': 1, }, plot_bgcolor="white", legend={'orientation': 'h', 'x': 0, 'y': 1.2}, )
def highlight_lines(fig: go.Figure, country: str) -> go.Figure: """Highlight lines of the infection plots""" if index := [i for i, c in enumerate(fig.data) if c["name"] == country]: fig.data[index[0]]["line"]["color"] = styles.highlight.color fig.data[index[0]]["line"]["width"] = styles.highlight.line_width fig.data[index[0]]["opacity"] = styles.highlight.opacity return fig
def _update_plot_layout(initial_layout: dict, update_layout: dict) -> Dict: if initial_layout is None: raise PreventUpdate fig = Figure({"layout": initial_layout}) if update_layout is not None: fig.update_layout(update_layout) return fig["layout"]
def configure_upset_plot_axes(fig: go.Figure, set_intersections: pd.DataFrame, truncated: bool, title: str) -> go.Figure: """ Format and organise plot axes for upset plotly figure :param fig: a go.Figure containing the plotly upsetplot :param set_intersections: pandas DataFrame with all set intersections :param truncated: boolean if the number of intersections has been truncated or not (i.e. if num intersections > MAX_UPSET_INTERSECTIONS) :param title: str containing the plot title :return: A go.Figure of the plotly upsetplot with tidied/formatted axes legends """ if truncated: plot_label = f"{title} UpSet Plot<br>(Truncated to {MAX_UPSET_INTERSECTIONS} Most "\ "Common Intersections)" else: plot_label = f"{title} UpSet Plot<br>(All Intersections)" fig.update_layout( dict( title=plot_label, # tidy axes for cardinality plot xaxis1=dict(showticklabels=False, fixedrange=True), yaxis1=dict(title="Set Count"), # grid xaxis2=dict(showticklabels=False, fixedrange=True, range=[-0.5, len(set_intersections.columns) - 0.5]), yaxis2=dict(showticklabels=False, fixedrange=True, range=[-0.5, len(set_intersections.index) + 0.5]), # membership xaxis3=dict(showticklabels=False, fixedrange=True, range=[-0.5, len(set_intersections.columns) - 0.5]), yaxis3=dict( tickmode='array', tickvals=list(range(len(set_intersections.index))), ticktext=set_intersections.index, title=f"{title}", fixedrange=True, range=[-0.5, len(set_intersections.index) + 0.5], tickfont=dict(size=10), automargin=True, ), # category count xaxis4=dict(title=f"Unique Count of<br>{title}"), yaxis4=dict(showticklabels=False, fixedrange=True, range=[-0.5, len(set_intersections.index) + 0.5]))) return fig
def _add_camera_trace( fig: go.Figure, cameras: CamerasBase, trace_name: str, subplot_idx: int, ncols: int, camera_scale: float, ): """ Adds a trace rendering a Cameras object to the passed in figure, with a given name and in a specific subplot. Args: fig: plotly figure to add the trace within. cameras: the Cameras object to render. It can be batched. trace_name: name to label the trace with. subplot_idx: identifies the subplot, with 0 being the top left. ncols: the number of sublpots per row. camera_scale: the size of the wireframe used to render the Cameras object. """ cam_wires = get_camera_wireframe(camera_scale).to(cameras.device) cam_trans = cameras.get_world_to_view_transform().inverse() cam_wires_trans = cam_trans.transform_points(cam_wires).detach().cpu() # if batch size is 1, unsqueeze to add dimension if len(cam_wires_trans.shape) < 3: cam_wires_trans = cam_wires_trans.unsqueeze(0) nan_tensor = torch.Tensor([[float("NaN")] * 3]) all_cam_wires = cam_wires_trans[0] for wire in cam_wires_trans[1:]: # We combine camera points into a single tensor to plot them in a # single trace. The NaNs are inserted between sets of camera # points so that the lines drawn by Plotly are not drawn between # points that belong to different cameras. all_cam_wires = torch.cat((all_cam_wires, nan_tensor, wire)) x, y, z = all_cam_wires.detach().cpu().numpy().T.astype(float) row, col = subplot_idx // ncols + 1, subplot_idx % ncols + 1 fig.add_trace( go.Scatter3d( # pyre-ignore [16] x=x, y=y, z=z, marker={"size": 1}, name=trace_name), row=row, col=col, ) # Access the current subplot's scene configuration plot_scene = "scene" + str(subplot_idx + 1) current_layout = fig["layout"][plot_scene] # flatten for bounds calculations flattened_wires = cam_wires_trans.flatten(0, 1) verts_center = flattened_wires.mean(0) max_expand = (flattened_wires.max(0)[0] - flattened_wires.min(0)[0]).max() _update_axes_bounds(verts_center, max_expand, current_layout)
def add_custom_hovercard(fig: go.Figure) -> None: """Add a custom hovercard to the figure based on the first element of customdata, without the title to the right. :param fig: Plotly figure. :type fig: go.Figure """ # Per https://stackoverflow.com/a/69430974/1840471. fig.update_traces(hovertemplate="%{customdata[0]}<extra></extra>")
def set_layout_size(fig: go.Figure, width: int, height: int, hsplit: int = 1, vsplit: int = 1) -> None: fig.update_layout( dict( autosize=False, width=width / hsplit, height=height / vsplit, ) )