def make_chart(ticker): from plotly.graph_objs import Scatter, Data, Line import requests from datetime import datetime import pandas as pd ticker = ticker.upper() url = 'https://min-api.cryptocompare.com/data/histoday?fsym={}&tsym=USDT&limit=119&aggregate=1'.format( ticker) response = requests.get(url) obj = response.json()['Data'] df = pd.DataFrame( obj, columns=['time', 'low', 'high', 'open', 'close', 'volume']) df.sort_values(by=['time'], inplace=True) dates = df['time'].map(datetime.fromtimestamp) df.loc[:, 'time'] = dates df.loc[:, 'moving'] = df['close'].rolling(window=20).mean() labels = dates.map('{:%Y-%m-%d}'.format)[19:].values price = Scatter(x=labels, y=df.loc[19:, 'close'], line=Line(width=2, color='blue'), name=ticker) moving = Scatter(x=labels, y=df.loc[19:, 'moving'], line=Line(width=2, color='orange'), name='20 Day Moving Avg') data = Data([price, moving]) return data
def plot(self, ax, X, Y, Z=None, color=None, label=None, line_kwargs=None, **kwargs): if 'mode' not in kwargs: kwargs['mode'] = 'lines' if Z is not None: return Scatter3d(x=X, y=Y, z=Z, showlegend=label is not None, line=Line(color=color, **line_kwargs or {}), name=label, **kwargs) return Scatter(x=X, y=Y, showlegend=label is not None, line=Line(color=color, **line_kwargs or {}), name=label, **kwargs)
def fill_gradient(self, canvas, X, percentiles, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs): if color.startswith('#'): colarray = Tango.hex2rgb(color) opacity = .9 else: colarray = list(map(float(color.strip(')').split('(')[1]))) if len(colarray) == 4: colarray, opacity = colarray[:3] ,colarray[3] alpha = opacity*(1.-np.abs(np.linspace(-1,1,len(percentiles)-1))) def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." from itertools import tee a, b = tee(iterable) next(b, None) return list(zip(a, b)) polycol = [] for i, y1, a in zip(list(range(len(percentiles))), percentiles, alpha): fcolor = 'rgba({}, {}, {}, {alpha})'.format(*colarray, alpha=a) if i == len(percentiles)/2: polycol.append(Scatter(x=X, y=y1, fillcolor=fcolor, showlegend=True, name=label, line=Line(width=0, smoothing=0), mode='none', fill='tonextx', legendgroup='density', hoverinfo='none', **kwargs)) else: polycol.append(Scatter(x=X, y=y1, fillcolor=fcolor, showlegend=False, name=None, line=Line(width=1, smoothing=0, color=fcolor), mode='none', fill='tonextx', legendgroup='density', hoverinfo='none', **kwargs)) return polycol
def plot_ribbon(df, x, ylower, yupper, name, ylab, ymax_factor=1, fillcolor='rgba(21,40,166,0.2)'): # Create a trace trace1 = go.Scatter(x=df[x], y=df[yupper], fill='tonexty', fillcolor=fillcolor, line=Line(color='transparent'), showlegend=False, name=name) trace2 = go.Scatter(x=df[x], y=df[ylower], fill='tonexty', fillcolor='transparent', line=Line(color='transparent'), showlegend=False, name=name) graph_data = [trace2, trace1] yaxis = dict(title=ylab, range=(0, max(df[yupper]) * ymax_factor)) graph_layout = go.Layout(yaxis=yaxis, showlegend=False) fig = go.Figure(data=graph_data, layout=graph_layout) return fig
def plot_loss(xs, p_loss, v_loss, title, filename): p_loss_color = 'rgb(0, 255, 0)' v_loss_color = 'rgb(255, 0, 0)' trace_p = Scatter(x=xs, y=p_loss, line=Line(color=p_loss_color), mode='lines', name='Policy Loss') trace_v = Scatter(x=xs, y=v_loss, line=Line(color=v_loss_color), mode='lines', name='Value Loss') plotly.offline.plot( { 'data': [trace_p, trace_v], 'layout': dict(title=title, xaxis={'title': 'Step'}, yaxis={'title': 'Average'}) }, filename=filename, auto_open=False)
def _addDetections(self, name, symbol, FP, TP): """Plot markers at anomaly detections; standard is for open shapes.""" symbol = symbol + "-open" # FPs: fpTrace = Scatter(x=FP["timestamp"], y=FP["value"], mode="markers", name=name, text=["anomalous data"], marker=Marker(color="rgb(200, 20, 20)", size=15.0, symbol=symbol, line=Line(color="rgb(200, 20, 20)", width=2))) # TPs: tpTrace = Scatter(x=[tp[1]["timestamp"] for tp in TP], y=[tp[1]["value"] for tp in TP], mode="markers", name=name, text=["anomalous data"], marker=Marker(color="rgb(20, 200, 20)", size=15.0, symbol=symbol, line=Line(color="rgb(20, 200, 20)", width=2))) return fpTrace, tpTrace
def plot_line(xs, ys_population): max_colour = 'rgb(0, 132, 180)' mean_colour = 'rgb(0, 172, 237)' std_colour = 'rgba(29, 202, 255, 0.2)' ys = torch.Tensor(ys_population) ys_min = ys.min(1)[0].squeeze() ys_max = ys.max(1)[0].squeeze() ys_mean = ys.mean(1).squeeze() ys_std = ys.std(1).squeeze() ys_upper, ys_lower = ys_mean + ys_std, ys_mean - ys_std trace_max = Scatter( x=xs, y=ys_max.numpy(), line=Line( color=max_colour, dash='dash'), name='Max') trace_upper = Scatter( x=xs, y=ys_upper.numpy(), line=Line(color='transparent'), name='+1 Std. Dev.', showlegend=False) trace_mean = Scatter( x=xs, y=ys_mean.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color=mean_colour), name='Mean') trace_lower = Scatter( x=xs, y=ys_lower.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color='transparent'), name='-1 Std. Dev.', showlegend=False) trace_min = Scatter( x=xs, y=ys_min.numpy(), line=Line( color=max_colour, dash='dash'), name='Min') plotly.offline.plot( { 'data': [trace_upper, trace_mean, trace_lower, trace_min, trace_max], 'layout': dict( title='Rewards', xaxis={'title': 'Step'}, yaxis={'title': 'Average Reward'}) }, filename=os.path.join('results', 'rewards.html'), auto_open=False)
def setUp(self): super(TestToDataframe, self).setUp() self.fig = Figure(data=Data([ Scatter(x=[52698, 43117], y=[53, 31], mode='markers', name='North America', text=['United States', 'Canada'], marker=Marker(color='rgb(164, 194, 244)', size=12, line=Line(color='white', width=0.5))), Scatter(x=[ 39317, 37236, 35650, 30066, 29570, 27159, 23557, 21046, 18007 ], y=[33, 20, 13, 19, 27, 19, 49, 44, 38], mode='markers', name='Europe', text=[ 'Germany', 'Britain', 'France', 'Spain', 'Italy', 'Czech Rep.', 'Greece', 'Poland' ], marker=Marker(color='rgb(255, 217, 102)', size=12, line=Line(color='white', width=0.5))), Scatter(x=[42952, 37037, 33106, 17478, 9813, 5253, 4692, 3899], y=[23, 42, 54, 89, 14, 99, 93, 70], mode='markers', name='Asia/Pacific', text=[ 'Australia', 'Japan', 'South Korea', 'Malaysia', 'China', 'Indonesia', 'Philippines', 'India' ], marker=Marker(color='rgb(234, 153, 153)', size=12, line=Line(color='white', width=0.5))), Scatter(x=[19097, 18601, 15595, 13546, 12026, 7434, 5419], y=[43, 47, 56, 80, 86, 93, 80], mode='markers', name='Latin America', text=[ 'Chile', 'Argentina', 'Mexico', 'Venezuela', 'Venezuela', 'El Salvador', 'Bolivia' ], marker=Marker(color='rgb(142, 124, 195)', size=12, line=Line(color='white', width=0.5))) ]), layout=Layout(title='Quarter 1 Growth', autosize=False, width=500, height=500, xaxis=XAxis(title='GDP per Capita', showgrid=False, zeroline=False), yaxis=YAxis(title='Percent', showline=False), margin=Margin(l=65, r=50, b=65, t=90)))
def population_plot(xs, ys, title, path): """Plots min, max and mean + standard deviation bars of a population over time. Parameters ---------- xs: iterations, list or numpy array, shape (N, ) ys: sum of rewards, list or numpy array, shape (N, num_epsd) title: figure title path: saving dir """ max_colour, mean_colour, std_colour = 'rgb(0, 132, 180)', 'rgb(0, 172, 237)', 'rgba(29, 202, 255, 0.2)' xs, ys = np.array(xs), np.array(ys) ys_min, ys_max = ys.min(1).squeeze(), ys.max(1).squeeze() ys_mean, ys_std = ys.mean(1).squeeze(), ys.std(1).squeeze() ys_upper, ys_lower = ys_mean + ys_std, ys_mean - ys_std trace_max = Scatter(x=xs, y=ys_max, line=Line(color=max_colour, dash='dash'), name='Max') trace_upper = Scatter(x=xs, y=ys_upper, line=Line(color='transparent'), name='+1 Std. Dev.', showlegend=False) trace_mean = Scatter(x=xs, y=ys_mean, fill='tonexty', fillcolor=std_colour, line=Line(color=mean_colour), name='Mean') trace_lower = Scatter(x=xs, y=ys_lower, fill='tonexty', fillcolor=std_colour, line=Line(color='transparent'), name='-1 Std. Dev.', showlegend=False) trace_min = Scatter(x=xs, y=ys_min, line=Line(color=max_colour, dash='dash'), name='Min') plotly.offline.plot( { 'data': [trace_upper, trace_mean, trace_lower, trace_min, trace_max], 'layout': dict(title=title, xaxis={'title': 'Iteration'}, yaxis={'title': title}) }, filename=os.path.join(path, title + '.html'), auto_open=False)
def _plot_line(xs, ys_population, title, path=''): max_colour, mean_colour, std_colour = 'rgb(0, 132, 180)', 'rgb(0, 172, 237)', 'rgba(29, 202, 255, 0.2)' ys = torch.tensor(ys_population, dtype=torch.float32) print("ys", ys) print('stats: min', ys.min()[0], 'max', ys.max()[0], 'mean', ys.mean(), 'std', ys.std()) #ys_min, ys_max, ys_mean, ys_std = ys.min(1)[0].squeeze(), ys.max(1)[0].squeeze(), ys.mean(1).squeeze(), ys.std(1).squeeze() ys_min, ys_max, ys_mean, ys_std = ys.min()[0], ys.max()[0], ys.mean( ), ys.std() ys_upper, ys_lower = ys_mean + ys_std, ys_mean - ys_std trace_max = Scatter(x=xs, y=ys_max.numpy(), line=Line(color=max_colour, dash='dash'), name='Max') trace_upper = Scatter(x=xs, y=ys_upper.numpy(), line=Line(color='lightcyan'), name='+1 Std. Dev.', showlegend=True) trace_mean = Scatter(x=xs, y=ys_mean.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color=mean_colour), name='Mean') trace_lower = Scatter(x=xs, y=ys_lower.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color='lightgreen'), name='-1 Std. Dev.', showlegend=False) trace_min = Scatter(x=xs, y=ys_min.numpy(), line=Line(color=max_colour, dash='dash'), name='Min') plotly.offline.plot( { 'data': [trace_upper, trace_mean, trace_lower, trace_min, trace_max], 'layout': dict(title=title, xaxis={'title': 'Step'}, yaxis={'title': title}) }, filename=os.path.join(path, title + '.html'), auto_open=False)
def OHLC_Line_Plots(): global fig from plotly.subplots import make_subplots import plotly.graph_objects as go from plotly.graph_objs import Line fig = make_subplots(rows=4, cols=1, subplot_titles=('Open', 'High', 'Low', 'Close')) fig.add_trace(Line(x=df.index, y=df.open), row=1, col=1) fig.add_trace(Line(x=df.index, y=df.high), row=2, col=1) fig.add_trace(Line(x=df.index, y=df.low), row=3, col=1) fig.add_trace(go.Line(x=df.index, y=df.close), row=4, col=1) fig.update_layout(height=1400, width=1000, title_text="OHLC Line Plots") fig.show() return go
def save_graph(xs, ys_pop, title, path=''): warnings.filterwarnings("ignore", category=DeprecationWarning) color_a, color_b, color_c = 'rgb(0, 132, 180)', 'rgb(0, 172, 237)', 'rgba(29, 202, 255, 0.2)' ys = np.asarray(ys_pop, dtype=np.float32) ys_max = ys.max(axis=1) ys_mean = ys.mean(axis=1) ys_min = ys.min(axis=1) ys_std = ys.std(axis=1) ys_upper, ys_lower = (ys_mean + ys_std), (ys_mean - ys_std) trace_max = Scatter(x=xs, y=ys_max, line=Line(color=color_a, dash='dash'), name='Max') trace_upper = Scatter(x=xs, y=ys_upper, line=Line(color='lightblue'), name='Mean + STD', showlegend=False) trace_mean = Scatter(x=xs, y=ys_mean, fill='tonexty', fillcolor=color_c, line=Line(color=color_b), name='Mean') trace_lower = Scatter(x=xs, y=ys_lower, fill='tonexty', fillcolor=color_c, line=Line(color='lightpink'), name='Mean - STD', showlegend=False) trace_min = Scatter(x=xs, y=ys_min, line=Line(color=color_a, dash='dash'), name='Min') plotly.offline.plot( { 'data': [trace_upper, trace_mean, trace_lower, trace_min, trace_max], 'layout': dict(title=title, xaxis={'title': 'Step'}, yaxis={'title': title}) }, filename=os.path.join(path, title + '.html'), auto_open=False)
def test_update_list_make_copies_false(self): trace1 = Scatter(x=[1, 2, 3], y=[2, 1, 2]) trace2 = Scatter(x=[1, 2, 3], y=[3, 2, 1]) data = Data([trace1, trace2]) update = dict(x=[2, 3, 4], y=[1, 2, 3], line=Line()) data.update(update, make_copies=False) assert data[0]["line"] is data[1]["line"]
def test_more_kwargs(self): self.assertAlmostEqual( tls.TraceFactory.create_quiver(x=[1, 2], y=[1, 2], u=[math.cos(1), math.cos(2)], v=[math.sin(1), math.sin(2)], arrow_scale=.4, angle=math.pi / 6, line=Line(color='purple', width=3)), { 'y': [ 1, 1.0841470984807897, None, 2, 2.0909297426825684, None, 1.044191642387781, 1.0841470984807897, 1.0658037346225067, None, 2.0677536925644366, 2.0909297426825684, 2.051107819102551, None ], 'x': [ 1, 1.0540302305868139, None, 2, 1.9583853163452858, None, 1.052143029378767, 1.0540302305868139, 1.0184841899864512, None, 1.9909870141679737, 1.9583853163452858, 1.9546151170949464, None ], 'line': { 'color': 'purple', 'width': 3 }, 'type': 'scatter', 'mode': 'lines', })
def get_traces(trace,value,type,color=None,width=.2,opacity=.3): if not is_list(value): value=[value]*len(trace['y']) if values_minus: if is_list(values_minus): min_value=values_minus else: min_value=[values_minus]*len(trace['y']) else: min_value=value if 'percent' in type: y_up=[trace['y'][_]*(1+value[_]/100.00) for _ in range(len(value))] y_down=[trace['y'][_]*(1-min_value[_]/100.00) for _ in range(len(min_value))] else: y_up=[trace['y'][_]+value[_] for _ in range(len(value))] y_down=[trace['y'][_]-min_value[_] for _ in range(len(min_value))] upper=Scatter(y=y_up,mode='lines',showlegend=False, line=Line(width=width),x=trace['x']) if 'yaxis' in trace: upper['yaxis']=trace['yaxis'] if color: color=normalize(color) else: if 'color' in trace['line']: color=trace['line']['color'] else: color='charcoal' color=to_rgba(color,opacity) if color else None upper['line']['color']=color lower=copy.deepcopy(upper) name=trace['name']+'_' if 'name' in trace else '' upper.update(name=name+'upper') color=to_rgba(normalize(color),opacity) lower.update(fill='tonexty',fillcolor=color,name=name+'lower',y=y_down) return upper,lower
def fill_between(self, ax, X, lower, upper, color=Tango.colorsHex['mediumBlue'], label=None, line_kwargs=None, **kwargs): if not 'line' in kwargs: kwargs['line'] = Line(**line_kwargs or {}) else: kwargs['line'].update(line_kwargs or {}) if color.startswith('#'): fcolor = 'rgba({c[0]}, {c[1]}, {c[2]}, {alpha})'.format( c=Tango.hex2rgb(color), alpha=kwargs.get('opacity', 1.0)) else: fcolor = color u = Scatter(x=X, y=upper, fillcolor=fcolor, showlegend=label is not None, name=label, fill='tonextx', legendgroup='{}_fill_({},{})'.format(label, ax[1], ax[2]), **kwargs) #fcolor = '{}, {alpha})'.format(','.join(fcolor.split(',')[:-1]), alpha=0.0) l = Scatter(x=X, y=lower, fillcolor=fcolor, showlegend=False, name=label, legendgroup='{}_fill_({},{})'.format(label, ax[1], ax[2]), **kwargs) return l, u
def _addValues(self): """Return data values trace.""" return Scatter(x=self.rawData["timestamp"], y=self.rawData["value"], name="Value", line=Line(width=1.5), showlegend=False)
def plot_mesh_via_plotly(in_mesh, colormap=cm.RdBu, plot_edges=None, vertex_color=None, show=True): '''Alternative to plotting a mesh with plotly.''' x = in_mesh.vertices[:, 0] y = in_mesh.vertices[:, 1] z = in_mesh.vertices[:, 2] simplices = in_mesh.triangles tri_vertices = map(lambda index: in_mesh.vertices[index], simplices) # vertices of the surface triangles I, J, K = ([triplet[c] for triplet in simplices] for c in range(3)) triangles = Mesh3d(x=x, y=y, z=z, i=I, j=J, k=K, name='', intensity=vertex_color) if plot_edges is None: # The triangle edges are not plotted. res = Data([triangles]) else: # Define the lists Xe, Ye, Ze, of x, y, resp z coordinates of edge end points for each triangle # None separates data corresponding to two consecutive triangles lists_coord = [[[T[k % 3][c] for k in range(4)] + [None] for T in tri_vertices] for c in range(3)] Xe, Ye, Ze = [reduce(lambda x, y: x + y, lists_coord[k]) for k in range(3)] # Define the lines to be plotted lines = Scatter3d(x=Xe, y=Ye, z=Ze, mode='lines', line=Line(color='rgb(50, 50, 50)', width=1.5)) res = Data([triangles, lines]) if show: iplot(res) else: return res
def test_update_list_make_copies_true(): trace1 = Scatter(x=[1, 2, 3], y=[2, 1, 2]) trace2 = Scatter(x=[1, 2, 3], y=[3, 2, 1]) data = Data([trace1, trace2]) update = dict(x=[2, 3, 4], y=[1, 2, 3], line=Line()) data.update(update, make_copies=True) assert data[0]['line'] is not data[1]['line']
def plot(self, x, y, plot_name, n_row, color, label): self.graphs_in_subplots[(plot_name, n_row)] = Scatter(x=x, y=y, line=Line(width=2, color=color), name=label) self.plot_summary[plot_name].add(n_row)
def make_scatter(x, y, color): return Scatter( x=x, y=y, mode='lines', line=Line(color=color, width=0.5), name=' ' # no name on hover )
def get_anomaly_scatter(df, detections, value_key): return Scatter(x=detections.index, y=[df.loc[index, value_key] for index in detections.index], mode="markers", name="Detected Anomaly", text=["anomalous data"], marker=Marker(color="rgb(200, 20, 20)", size=15.0, symbol='circle', line=Line(color="rgb(200, 20, 20)", width=2)))
def _addValues(data, start=None, end=None): """Return data values trace.""" if start is None: start = data["timestamp"][0] if end is None: end = data["timestamp"].iloc[-1] mask = ((data["timestamp"] >= start) & (data["timestamp"] <= end)) return Scatter(x=data["timestamp"][mask], y=data["value"][mask], name="value", line=Line(width=1.5), showlegend=False)
def test_simple(self): self.assertEqual( (tls.TraceFactory.create_streamline(x=[0, 2], y=[0, 2], u=[[-1, -5], [-1, -5]], v=[[1, 1], [-3, -3]], density=2, arrow_scale=.4, angle=math.pi / 6, line=Line(color='purple', width=3))).keys(), (['y', 'x', 'line', 'type', 'mode']))
def plot(self, x, y, graph_name, subplot_name, color, label): """Main function used to generate graphs in a comparatively simple API input: ===== x: data in x-axis y: data in y-axis graph_name: the name shown in the selector. All graphs with the same graph_name will be shown together subplot_name: the title of each subgraph color: the color of the curve label: the label of the curve """ self.graphs[graph_name][subplot_name].append( Scatter(x=x, y=y, line=Line(width=2, color=color), name=label))
def _addValues(self, name=None, title=None): """Return data values trace.""" if name is None: name = "value" if title is None: title = "Value" return Scatter(x=self.rawData["timestamp"], y=self.rawData[name], name=title, line=Line( width=1.5 ), yaxis="y1", showlegend=False)
def graph_cols(df, tick, column, title, user): import pandas as pd from plotly.graph_objs import Scatter, Data, Line, Figure df = df[df['ticker'] == tick][column] * user.get_mult() dates = pd.to_datetime(df.index, format='%Y%m%d%H%M%S%f') price = Scatter(x=dates, y=df, line=Line(width=2, color='blue'), name=tick) layout = dict(title=title) data = Data([price]) fig = Figure(data=data, layout=layout) return fig
def _plotly_3d_scatter(coords, partition=None): """ _plotly_3d_scatter(coords, partition=None) Make a scatterplot of treeCl.CoordinateMatrix using the Plotly plotting engine """ from plotly.graph_objs import Scatter3d, Data, Figure, Layout, Line, Margin, Marker # auto sign-in with credentials or use py.sign_in() colourmap = { 'A': '#1f77b4', 'B': '#ff7f0e', 'C': '#2ca02c', 'D': '#d62728', 'E': '#9467bd', 1: '#1f77b4', 2: '#ff7f0e', 3: '#2ca02c', 4: '#d62728', 5: '#9467bd' } df = coords.df if partition: assert len(partition.partition_vector) == df.shape[0] labels = [x + 1 for x in partition.partition_vector] else: labels = [1 for _ in range(df.shape[0])] x, y, z = df.columns[:3] df['Label'] = labels colours = [colourmap[lab] for lab in df['Label']] trace = Scatter3d(x=df[x], y=df[y], z=df[z], mode='markers', marker=Marker(size=9, color=colours, line=Line(color=colours, width=0.5), opacity=0.8), text=[str(ix) for ix in df.index]) data = Data([trace]) layout = Layout( margin=Margin(l=0, r=0, b=0, t=0), hovermode='x', ) fig = Figure(data=data, layout=layout) return fig
def forecast_route(): forecast_date = [] forecast_value = [] forecast_date.append( pd.Timestamp( np.datetime64(model_data.pre_processing.df.iloc[-1, 0], 'D') + 1)) forecast_value.append( forecast(model_data.pre_processing.df, model_data.seq_len, model)) graphs = [{ 'data': [ Line(x=model_data.pre_processing.df['date'], y=model_data.pre_processing.df['close'], name='BTC-GBP Actual'), Line(x=forecast_date, y=forecast_value, name='BTC-GBP Forecast', width=4) ], 'layout': { 'title': 'BTC-GBP Forecast', 'yaxis': { 'title': "BTC Close Returns (7d ma)" }, 'xaxis': { 'title': "Day" } } }] # encode plotly graphs in JSON ids = ["graph-{}".format(i) for i, _ in enumerate(graphs)] graphJSON = json.dumps(graphs, cls=plotly.utils.PlotlyJSONEncoder) # render web page with plotly graphs return render_template('master.html', ids=ids, graphJSON=graphJSON)
def get_labels_scatter(data_df, labels_df, value_key): anomaly_indices = labels_df[labels_df[value_key] > 0].index return Scatter(x=anomaly_indices, y=[ data_df.loc[index, value_key] if index in data_df.index else 0 for index in anomaly_indices ], mode="markers", name="Anomaly", text=["Anomalous Instance"], marker=Marker(color="rgb(20, 200, 20)", size=15.0, symbol='diamond', line=Line(color="rgb(20, 200, 20)", width=2)))