Pandas Plotly -- Secondary Graph needs to be to RSI - pandas

In plotly, I am able to make this graph(Attached picture at the end), with the code below.
(Data is stock market data for 1year, which is in csv format. Please use any OHLC data which has about 200 to 300 rows)
import pandas as pd
import ta
import plotly.graph_objects as go
df = pd.read_csv("Trial.csv")
df["rsi"] = ta.momentum.rsi(df["Close"], window=14, fillna=False)
dfff = df.tail(180)
layoutt = go.Layout(autosize=False, width=4181, height=1597)
fig_001 = go.Figure(data=[go.Candlestick(x=dfff['Date'], open=dfff['Open'], high=dfff['High'], low=dfff['Low'], close=dfff['Close'])], layout=layoutt)
fig_001.write_image("fig_001.jpeg")
As you see in the attached picture below, Plotly is generating 2 charts by default (with a smaller-duplicated chart below)...
About the secondary graph which is enclosed in 'Green', how can I change that to a RSI graph((Which is currently the same candlestick data as in red))?

plotly is not generating two charts. It is one with a range slider (when interactive can use to zoom into xaxis)
have hidden range slider
have created an additional trace and set it to use a second yaxis
have configure yaxes to use domains so it has same visual effect
import pandas as pd
import ta
import plotly.graph_objects as go
# df = pd.read_csv("Trial.csv")
# use plotly OHLC sample data
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv"
)
df = df.rename(columns={c: c.split(".")[1] for c in df.columns if "." in c})
df["rsi"] = ta.momentum.rsi(df["Close"], window=14, fillna=False)
dfff = df.tail(180)
layoutt = go.Layout(autosize=False, width=4181, height=1597)
# make it fit on my screen!!!
layoutt = go.Layout(autosize=True)
layoutt2 = go.Layout(autosize=False, width=6731, height=2571)
fig_001 = go.Figure(
data=[
go.Candlestick(
x=dfff["Date"],
open=dfff["Open"],
high=dfff["High"],
low=dfff["Low"],
close=dfff["Close"],
name="OHLC",
),
go.Scatter(
x=dfff["Date"], y=dfff["rsi"], mode="markers+lines", name="RSI", yaxis="y2"
),
],
layout=layoutt,
).update_layout(
yaxis_domain=[0.3, 1],
yaxis2={"domain": [0, 0.20]},
xaxis_rangeslider_visible=False,
showlegend=False,
)
fig_001

Related

Is there any way to show gray color to states which are not having any data in Plotly map?

I need to show gray color to the states which do not have any data in Plotly.
Sample csv file is: (This states have data)
States which are not having data are: (I have filled the missing values as -1
The current plots generated are: ( I need to show gray color to the states with missing data.
Thanks!
Your solution is to use custom colorscale in combination with
import plotly.express as px
px.choropleth_mapbox
The following is an example on how to use custom colorscale:
import plotly.plotly as py
import plotly.graph_objs as go
import numpy as np
import copy
import pandas as pd
# Read data from a csv
z_data = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')
z=z_data.values.copy()
# Compute surface color with nan's
surfacecolor = z.copy()
surfacecolor[-10:, -10:] = np.nan
# Replace nans with -100
surfacecolor[np.isnan(surfacecolor)] = -100
# Build surface trace
data = [
go.Surface(
z=z,
surfacecolor=surfacecolor,
cmin = -5,
cmax = 350,
colorscale=[[0, 'gray'],
[0.01, 'gray'],
[0.01, 'blue'],
[1, 'red']]
)
]
# Build layout
layout = go.Layout(
title='Mt Bruno Elevation',
autosize=False,
width=500,
height=500,
margin=dict(
l=65,
r=50,
b=65,
t=90
)
)
fig = go.FigureWidget(data=data, layout=layout)
fig
A similar question has been solved by the plotly community forum.
Please find the plotly documentation on how to define custom colorscales.
Hope this solves your issue!

Add a slider to plotly that dynamically changes a column of data frame that is displayed

Minimal working example:
import pandas as pd
import plotly.express as px
A = [10,20,30,40,50,60]
B = [40,50,60,10,20,30]
data = pd.DataFrame({"A":A,"B":B})
alpha=0.5
data["Parameter"]= alpha*data["A"] +(1-alpha)*data["B"]
fig = px.scatter(
data, x="A",y="B",color="Parameter"
)
fig.show()
I would like to have a slider for alpha in plotly graph. I looked at the documentation but only found a slider for a fixed column with constant values.
fig = px.scatter(data, x="A", y="B", color="Parameter", animation_frame='Parameter')
fig["layout"].pop("updatemenus")
fig.update_xaxes(range=[0, 100])
fig.show('browser')

Plotly chart percentage with smileys

I would like o add a plot figure based on smileys like this one:
dat will come from a dataframe pandas : dataframe.value_counts(normalize=True)
Can some one give me some clues.
use colorscale in normal way for a heatmap
use anotation_text to assign an emoji to a value
import plotly.figure_factory as ff
import plotly.graph_objects as go
import pandas as pd
import numpy as np
df = pd.DataFrame([[j*10+i for i in range(10)] for j in range(10)])
e=["😃","🙂","😐","☚ī¸"]
fig = go.Figure(ff.create_annotated_heatmap(
z=df.values, colorscale="rdylgn", reversescale=False,
annotation_text=np.select([df.values>75, df.values>50, df.values>25, df.values>=0], e),
))
fig.update_annotations(font_size=25)
# allows emoji to use background color
fig.update_annotations(opacity=0.7)
update coloured emoji
fundamentally you need emojicons that can accept colour styling
for this I switched to Font Awesome. This then also requires switching to dash, plotly's cousin so that external CSS can be used (to use FA)
then build a dash HTML table applying styling logic for picking emoticon and colour
from jupyter_dash import JupyterDash
import dash_html_components as html
import pandas as pd
import branca.colormap
# Load Data
df = pd.DataFrame([[j*10+i for i in range(10)] for j in range(10)])
external_stylesheets = [{
'href': 'https://use.fontawesome.com/releases/v5.8.1/css/all.css',
'rel': 'stylesheet', 'crossorigin': 'anonymous',
'integrity': 'sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf',
}]
# possibly could use a a different library for this - simple way to map a value to a colormap
cm = branca.colormap.LinearColormap(["red","yellow","green"], vmin=0, vmax=100, caption=None)
def mysmiley(v):
sm = ["far fa-grin", "far fa-smile", "far fa-meh", "far fa-frown"]
return html.Span(className=sm[3-(v//25)], style={"color":cm(v),"font-size": "2em"})
# Build App
app = JupyterDash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Table([html.Tr([html.Td(mysmiley(c)) for c in r]) for r in df.values])
])
# Run app and display result inline in the notebook
app.run_server(mode='inline')

Plotly scatterplot using pandas groupby for traces

I run into this pattern quite often. I want my traces to be the results of a groupby operation.
data = dict(
time = [1,1,1,2,2,2,3,3,3],
satellite_ID = [3,24,9,3,24,9,3,24,9],
satellite_type = ['gps','glonass','galileo']*3,
snr = [28,34,26,27,35,25,28,36,24])
df = pd.DataFrame(data)
The x-axis is time, the y-axis is SNR, and each line+marker trace is a unique satellite ID. There should be 3 traces at time 1, 2, and 3 for each satellite. A nice addition would be to have each satellite_type be a different color and visible on mouse hover.
I think I figured it out from the documentation.
import plotly.express as px
import pandas as pd
data = dict(
time = [1,1,1,2,2,2,3,3,3],
satellite_ID = [3,24,9,3,24,9,3,24,9],
satellite_type = ['gps','glonass','galileo']*3,
snr = [28,34,26,27,35,25,28,36,24])
df = pd.DataFrame(data)
fig = px.line(df, x="time", y="snr", color='satellite_ID',
hover_data=['satellite_type'] )
fig.update_traces(mode="markers+lines")
"color" selects the traces, and additional hover data can be entered using the "hover_data' argument to px.line.

Time series plot of categorical or binary variables in pandas or matplotlib

I have data that represent a time series of categorical variables. I want to display the transitions in categories below a traditional line plot of related continuous time series to show off context as time evolves. I'd like to know the best way to do this. My attempt was in terms of Rectangles. The appearance is a bit weird, and importantly the axis labels for the x axis don't render as dates.
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from pandas.plotting import register_matplotlib_converters
import matplotlib.dates as mdates
register_matplotlib_converters()
t0 = pd.DatetimeIndex(["2017-06-01 00:00","2017-06-17 00:00","2017-07-03 00:00","2017-08-02 00:00","2017-08-09 00:00","2017-09-01 00:00"])
t1 = pd.DatetimeIndex(["2017-06-01 00:00","2017-08-15 00:00","2017-09-01 00:00"])
df0 = pd.DataFrame({"cat":[0,2,1,2,0,1]},index = t0)
df1 = pd.DataFrame({"op":[0,1,0]},index=t1)
# Create new plot
fig,ax = plt.subplots(1,figsize=(8,3))
data_layout = {
"cat" : {0: ('bisque','Low'),
1: ('lightseagreen','Medium'),
2: ('rebeccapurple','High')},
"op" : {0: ('darkturquoise','Open'),
1: ('tomato','Close')}
}
vars =("cat","op")
dfs = [df0,df1]
all_ticks = []
leg = []
for j,(v,d) in enumerate(zip(vars,dfs)):
dvals = d[v][:].astype("d")
normal = mpl.colors.Normalize(vmin=0, vmax=2.)
colors = plt.cm.Set1(0.75*normal(dvals.as_matrix()))
handles = []
for i in range(d.count()-1):
s = d[v].index.to_pydatetime()
level = d[v][i]
base = d[v].index[i]
w = s[i+1] - s[i]
patch=mpl.patches.Rectangle((base,float(j)),width=w,color=data_layout[v][level][0],height=1,fill=True)
ax.add_patch(patch)
for lev in data_layout[v]:
print data_layout[v][level]
handles.append(mpl.patches.Patch(color=data_layout[v][lev][0],label=data_layout[v][lev][1]))
all_ticks.append(j+0.5)
leg.append( plt.legend(handles=handles,loc = (3-3*j+1)))
plt.axhline(y=1.,linewidth=3,color="gray")
plt.xlim(pd.Timestamp(2017,6,1).to_pydatetime(),pd.Timestamp(2017,9,1).to_pydatetime())
plt.ylim(0,2)
ax.add_artist(leg[0]) # two legends on one axis
ax.format_xdata = mdates.DateFormatter('%Y-%m-%d') # This fails
plt.yticks(all_ticks,vars)
plt.show()
which produces this with no dates and has jittery lines:. How do I fix this? Is there a better way entirely?
This is a way to display dates on x-axis:
In your code substitute the line that fails with this one:
ax.xaxis.set_major_formatter((mdates.DateFormatter('%Y-%m-%d')))
But I don't remember how it should look like, can you show us the end-result again?