How to plot green and red arrows over a plotly CandleStick graph? - python

I have tried to plot the Candle Sticks for my data using the plotly library with Python. Using the typical plotting way, I got the following graph:
Candle = go.Candlestick(x=stock.index,
open=stock.open,
high=stock.high,
low=stock.low,
close=stock.close
)
Output:
I was expecting to draw the image is something like the following:
See the up green arrow and the down red arrow. I want to know how to plot that.

I don't know which one is the logic for selecting arrows but you can play from here. First download data from Yahoo-finance TESLA and then
import plotly.offline as py
import plotly.graph_objs as go
import pandas as pd
import numpy as np
stock = pd.read_csv("~/Downloads/TSLA.csv")
d=3
stock["Marker"] = np.where(stock["Open"]<stock["Close"], stock["High"]+d, stock["Low"]-d)
stock["Symbol"] = np.where(stock["Open"]<stock["Close"], "triangle-up", "triangle-down")
stock["Color"] = np.where(stock["Open"]<stock["Close"], "green", "red")
Candle = go.Candlestick(x=stock.Date,
open=stock.Open,
high=stock.High,
low=stock.Low,
close=stock.Close
)
Trace = go.Scatter(x=stock.Date,
y=stock.Marker,
mode='markers',
name ='markers',
marker=go.Marker(size=20,
symbol=stock["Symbol"],
color=stock["Color"])
)
py.plot([Candle, Trace])

Related

Python 3 does not show the barchart

I am trying to make this bargraph appear in the python run screen. But for some reason, it does not show the graph on the screen. However, if I put this code on the google online coding website, it shows the bar graph fine. Can anyone let me know what the problem is?
import pandas as pd
import plotly.express as px
df = pd.read_csv("Diversity2.csv")
df = df.groupby(['School','White'], as_index=False)[['School']].sum()
# df = df.groupby(['School','White']).sum().plot(kind='bar')
df['White']=df['White'].astype(float)
# df.plot(kind='bar', x='School', y='White', figsize=(20,10))
barchart = px.bar(
data_frame=df,
x="School",
y="White",
color="School",
opacity=0.9,
orientation="v",
barmode='overlay')
barchart.show()

How to get rid of the grey top and right line in Altair?

I was trying to visualise a result of linear regression. And I wanted to remove the top and right grey line. I have tried setting stroke=None, strokeWidth=0 and strokeOpacity=0 in global config but none of these worked. How can I get rid of them?
Here's my code and plot.
import altair as alt
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
alt.renderers.enable('altair_viewer')
alt.data_transformers.disable_max_rows()
df = pd.read_csv('~/Desktop/py/ukb.csv')
chart = alt.Chart(df).mark_point(color='gray', opacity=0.1).encode(
alt.X(
'loneliness:O',
axis=alt.Axis(title='Loneliness', grid=False, labelAngle=0)
),
alt.Y('v_rvlpfc:Q',
scale=alt.Scale(zero=False),
axis=alt.Axis(title='GMV of RVLPFC', grid=False)
)
).properties(
height=400,
width=400,
)
chart = chart + chart.transform_regression('loneliness','v_rvlpfc').mark_line(color='red')
chart.configure_view(stroke=None)
chart.show()
enter image description here
If you remove the last chart.show() or do chart = chart.configure_view(stroke=None) it will work. Currently you are not saving the modified chart.configure_view(stroke=None) back to the chart variable, and your last line displays the original chart variable without any modification to the stroke.

Plotting a pie chartof value_counts() using plotly express

How does one plot a pie for value_counts() using plotly express for the following series:
import pandas as pd
import string, random
s = pd.Series(random.choice(string.ascii_uppercase) for _ in range(100))
I can see that it can be done through go using:
import plotly.graph_objects as go
go.Figure(data=[go.Pie(labels=s.value_counts().index, values=s.value_counts().values)])
There are four display types, label, text, value and percentage, which can be combined. Reference page
import plotly.express as px
fig = px.pie(s, values=s.value_counts().values, names=s.value_counts().index)
fig.update_traces(hoverinfo='label+percent', textinfo='value')
fig.show()

Plotly: How to add vertical lines at specified points?

I have a data frame plot of a time series along with a list of numeric values at which I'd like to draw vertical lines. The plot is an interactive one created using the cufflinks package. Here is an example of three time series in 1000 time values, I'd like to draw vertical lines at 500 and 800. My attempt using "axvlinee" is based upon suggestions I've seen for similar posts:
import numpy as np
import pandas as pd
import cufflinks
np.random.seed(123)
X = np.random.randn(1000,3)
df=pd.DataFrame(X, columns=['a','b','c'])
fig=df.iplot(asFigure=True,xTitle='time',yTitle='values',title='Time Series Plot')
fig.axvline([500,800], linewidth=5,color="black", linestyle="--")
fig.show()
The error message states 'Figure' object has no attribute 'axvline'.
I'm not sure whether this message is due to my lack of understanding about basic plots or stems from a limitation of using igraph.
The answer:
To add a line to an existing plotly figure, just use:
fig.add_shape(type='line',...)
The details:
I gather this is the post you've seen since you're mixing in matplotlib. And as it has been stated in the comments, axvline has got nothing to do with plotly. That was only used as an example for how you could have done it using matplotlib. Using plotly, I'd either go for fig.add_shape(go.layout.Shape(type="line"). But before you try it out for yourself, please b aware that cufflinks has been deprecated. I really liked cufflinks, but now there are better options for building both quick and detailed graphs. If you'd like to stick to one-liners similat to iplot, I'd suggest using plotly.express. The only hurdle in your case is changing your dataset from a wide to a long format that is preferred by plotly.express. The snippet below does just that to produce the following plot:
Code:
import numpy as np
import pandas as pd
import plotly.express as px
from plotly.offline import iplot
#
np.random.seed(123)
X = np.random.randn(1000,3)
df=pd.DataFrame(X, columns=['a','b','c'])
df['id'] = df.index
df = pd.melt(df, id_vars='id', value_vars=df.columns[:-1])
# plotly line figure
fig = px.line(df, x='id', y='value', color='variable')
# lines to add, specified by x-position
lines = {'a':500,'c':700,'a':900,'b':950}
# add lines using absolute references
for k in lines.keys():
#print(k)
fig.add_shape(type='line',
yref="y",
xref="x",
x0=lines[k],
y0=df['value'].min()*1.2,
x1=lines[k],
y1=df['value'].max()*1.2,
line=dict(color='black', width=3))
fig.add_annotation(
x=lines[k],
y=1.06,
yref='paper',
showarrow=False,
text=k)
fig.show()
Not sure if this is what you want, adding two scatter seems to work:
np.random.seed(123)
X = np.random.randn(1000,3)
df=pd.DataFrame(X, columns=['a','b','c'])
fig = df.iplot(asFigure=True,xTitle='time',yTitle='values',title='Time Series Plot')
fig.add_scatter(x=[500]*100, y=np.linspace(-4,4,100), name='lower')
fig.add_scatter(x=[800]*100, y=np.linspace(-4,4,100), name='upper')
fig.show()
Output:

Plotly: How to plot a cumulative "steps" histogram?

I am trying to plot a cumulative histogram using Plotly in python, but make it look like "steps", i.e. bars with no color and only the top line is displayed. Something like this:
Basically, I'm trying to reproduce the behavior of the following matplotlib code:
import matplotlib.pyplot as plt
plt.hist(x, cumulative=True, histtype='step')
So far, the best I've been able to do is:
import plotly.graph_objs as go
from plotly.offline import iplot
h = go.Histogram(x=x,
cumulative=dict(enabled=True),
marker=dict(color="rgba(0,0,0,0)",
line=dict(color="red", width=1)))
iplot([h])
Which results in something like:
So what's the trick?
If you're willing to handle the binning and accumulation before you plot the data, you can use a go.Scatter object with the shape property of the line set to 'hvh'.
Plot:
Code: Setup for a Jupyter Notebook
#imports
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import numpy as np
import pandas as pd
# qtconsole for debugging
#%qtconsole -- style vim
# Notebook settings
init_notebook_mode(connected=True)
# Some sample data
x = np.random.normal(50, 5, 500)
binned = np.histogram(x, bins=25, density=True)
plot_y = np.cumsum(binned[0])
# Line
trace1 = go.Scatter(
x=binned[1],
y=plot_y,
mode='lines',
name="X",
hoverinfo='all',
line=dict(color = 'rgb(1255, 0, 0)', shape='hvh'
)
)
data = [trace1]
# Layout
layout = dict(title = 'Binned data from normal distribution',
legend=dict(
y=0.5,
traceorder='reversed',
font=dict(
size=16
)
)
)
# Make figure
fig = dict(data=data, layout=layout)
# Plot
iplot(fig, filename='line-shapes')
I hope this is something you can use!
Don't hesitate to let me know if not.
Some details:
The data sample is made using np.random.normal(). x is a sampled normal distribution with mean = 50, sigma = 5 and 500 observations. x is then put in 50 bins using np.histogram() which returns two arrays. These are used as data source for the plot.
Possible alternative approaches:
I also tried using your snippet with some random sample data and include shape='hvh' in your line=dict(color="red", width=1). That did not seem to work though. I also considered modifying the layout of your go.Histogram() so that only the top line of the bars were plotted, but I don't think it's possible.
The accepted solution works but may be limiting as the bins are all of equal width. One approach is to use matplotlib to calculate stats, then plot with plotly:
# sample data
# I am not using a normal distribution on purpose so that the effect of varying bin widths is apparent.
x = np.random.rand(100)
# use matplotlib to get "n" and "bins"
# n_bins will affect the resolution of the cumilative histogram but not dictate the bin widths.
n_bins = 100
n, bins, patches = plt.hist(x, n_bins, density=True, histtype='step', cumulative=-1)
# use plotly (v3) to plot
data = []
trace = go.Scatter(
x=bins,
y=n,
mode='lines',
name= "test",
line=dict(
shape='hvh'
)
)
data.append(trace)
fig = go.Figure(data=data)
iplot(fig)
The result should look something like this:

Categories