I am using Plotly API to draw line charts from a dataset in python. For example I have this dataset from the year 2018.
Now I want to check weather the weekend days have higher demand in contrast to the weekdays. My goal is to mark the lines in the diagram for saturday and sunday.
Does Plotly provide methods to do this? If not, is there any easy method to achieve this?
You can make a marker plot and then overlay a line plot to get the desired output where the marker plot must be passed with a list of colors that is made based on the condition.
To get a clear picture see the below codes,
# make a dummy time data
x_values = pd.date_range(start=pd.Timestamp('2018-01-01'), end=pd.Timestamp('2019-01-01'), freq='1 D')
# making a random time series
y_values = np.random.randn(len(x_values))
# making color list
# red if the day is saturday or sunday else green
colors = ['red' if int(pd.Timestamp(d).weekday()) >= 5 else 'green' for d in x_values]
# make the plot
trace_0 = go.Scatter(
x=x_values,
y=y_values,
mode='markers',
marker=dict(
color = colors
)
)
trace_1 = go.Scatter(
x=x_values,
y=y_values,
mode='lines',
marker=dict(
color = 'black'
)
)
layout = dict(
title='Time Series with Rangeslider',
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(count=1,
label='1m',
step='month',
stepmode='backward'),
dict(count=6,
label='6m',
step='month',
stepmode='backward'),
dict(step='all')
])
),
rangeslider=dict(
visible = True
),
type='date'
)
)
fig = {
'data': [trace_0, trace_1],
'layout': layout,
}
py.iplot(fig, filename='Plot')
Output plot
I have also implemented a range slider, if that is not needed edit it out from the layout.
Related
I have to plot some chronologically-ordered values (one value per month, in my case) on a Plotly (Python) graph. Also, I have to add a "end of period label" (i.e. a marker with text indicating the last value of the series) that has to be positioned at 'middle right'.
A working example would be something like this:
import pandas as pd
import numpy as np
import plotly.graph_objects as go
date_range = pd.to_datetime(pd.date_range(start='1/1/2013', end='9/1/2022', freq='M').tolist()).date
values = np.random.randint(100, size=len(date_range)).tolist()
fig = go.Figure(
)
fig.add_trace(go.Scatter(
showlegend=False,
x=date_range,
y=values,
mode='lines',
line=dict(
width=2,
color="red",
)
)
)
fig.add_trace(go.Scatter(
showlegend=False,
x=[date_range[-1]],
y=[values[-1]],
text=[values[-1]],
textposition='middle right',
texttemplate="%{text:.3f}",
mode='markers+text',
line=dict(
width=2,
color="red",
)
)
)
fig.update_layout(
xaxis=dict(
tickformat="%m\n<b>%Y", dtick="M3",
)
)
which produces the following plot:
I am facing the following problem: the end of period label "extends" beyond the last value of the date range and makes the x axis go into the green area, which are all undesired months (for example, those that extend beyond the last value of the date range and into 2023).
I tried several things to "erase" or delete that undesired part of the x axis, but nothing worked properly: either the end of period label was cut in half or the whole x axis disappeared.
Thank you in advance for any help or suggestion.
as per #r0beginners comments
given text is outside graph area use an annotation for the text
make marker scatter just mode=markers
explicitly state xaxis range range=date_range[[0,-1]]
import pandas as pd
import numpy as np
import plotly.graph_objects as go
date_range = pd.to_datetime(
pd.date_range(start="1/1/2013", end="9/1/2022", freq="M").tolist()
).date
values = np.random.randint(100, size=len(date_range)).tolist()
fig = go.Figure()
fig.add_trace(
go.Scatter(
showlegend=False,
x=date_range,
y=values,
mode="lines",
line=dict(
width=2,
color="red",
),
)
)
fig.add_trace(go.Scatter(
showlegend=False,
x=[date_range[-1]],
y=[values[-1]],
mode='markers',
marker_size=15
)
)
fig.add_annotation(
x = date_range[-1],
y = values[-1],
text = values[-1],
xshift=10,
yshift=0,
showarrow=False
)
fig.update_layout(
xaxis=dict(
tickformat="%m\n<b>%Y",
dtick="M3",
range=date_range[[0,-1]]
)
)
I'm pretty new using plotly in python. I managed to plot a box chart with my dataframe in plotly like this:
box chart
The box plot shows the entire department's performance. I wish to add a few buttons that filter or narrow down the result. For example:
Team 1 button - filter on JH, DT, MB, SC
Team 2 button - filter on NP, DH, MZ, SB
Team 3 button - filter on KT, BL, SM,LW
and so on
I read through the plotly Figure reference (https://plotly.com/python/reference/layout/updatemenus/#layout-updatemenus-items-updatemenu-buttons-items-button-args)
and managed to add the buttons with args=["Claim_Handler"] where ["Claim_Handler"] is the column name in my dataframe. However the button does not perform any action when I click on it.
Where did I do wrong?
Here is the code for the graph:
fig2 = px.box(DF2, x='Claim_Handler', y='Days_to_close',hover_data=["Claim#"])
fig2.update_layout(
title='Average days to close for Claims Closed in last 5 years',
xaxis = dict(
rangeslider = dict(
visible=True,
thickness=0.05
)
),
yaxis = dict(
),
barmode='stack',
paper_bgcolor='#FFFFFF',
showlegend=True
)
fig2.update_layout(
updatemenus=[
dict(
type = "buttons",
direction = "left",
buttons=list([
dict(
args=["Claim_Handler"],
label="DH",
method="update"
),
dict(
args=["Claim_Handler"],
label="DT",
method="update"
)
])
),]
)
fig2.show(renderer="iframe")
Following is my input file i'm trying to display on a map using plotly.
data.csv
lat,long,type
-7.80715,110.371203,1
-7.791087,110.368346,3
-7.778744,110.365107,7
-7.77877,110.365379,4
The script works but the scale is displayed in a continuous format. I tried to convert the column type to text as mentioned here but I couldn't get it to work. Is there a easier way to fix this problem?
df = pd.read_csv("data.csv").dropna()
fig = go.Figure(go.Scattermapbox(
lat=df["lat"].tolist(),
lon=df["long"].tolist(),
mode='markers',
text=df['type'].tolist(),
marker=go.scattermapbox.Marker(
size=10,
color=df['type'],
showscale=True
),
))
fig.show()
If you want to specify a discrete color, you can either deal with it directly as a list of color specifications, or you can specify the default color name in plotly_express.
import plotly.graph_objects as go
import plotly.express as px
mapbox_access_token = open("mapbox_api_key.txt").read()
colors = px.colors.qualitative.D3
fig = go.Figure(go.Scattermapbox(
lat=df["lat"].tolist(),
lon=df["long"].tolist(),
mode='markers',
text=df['type'].tolist(),
marker=go.scattermapbox.Marker(
size=10,
color=colors,
showscale=False
),
))
fig.update_layout(
autosize=False,
height=450,
width=1000,
mapbox=dict(
accesstoken=mapbox_access_token,
style="outdoors",
center=dict(
lat=-7.78,
lon=110.365
),
zoom=10),
showlegend = False
)
fig.show()
Hi I am having trouble getting a lineplot to display properly. I have two axes and 5 line plots on one figure. The first y-axis limit cannot be set. I tried setting the range property to [0,2], however it doesn't do anything and continues to show from -2 to 4. I want the straight linear plot to overlay directly on top of the other 4 line plots and I don't know why the x-axis starts from -5. Can someone help fix the issue?
fig = go.Figure()
xs = np.linspace(0,12.5,plot_df.shape[0])
for cn in plot_df.columns:
ys = plot_df[cn].to_numpy()
fig.add_trace(go.Scatter(x=xs, y=ys,
mode='lines',
name=cn)
)
fig.add_trace(go.Scatter(x=xs, y=xs,
mode='lines',
name='mob. grad', yaxis="y2")
)
fig.update_layout(
title = "UV and Mobile phase trace of {}".format(field_dict['sample_name']),
xaxis = dict(
title = "Minutes",
domain=[0.2, 1]
),
yaxis = dict(
scaleanchor = "x",
title = "UV Abs",
range = [0,2],
position = 0.19
),
yaxis2 = dict(
title = "Mobile Phase (%)",
anchor="free",
domain=[0.1,1],
overlaying="y",
side="left",
position=0.08,
range=[0,100])
)
fig.show()
I just removed scaleanchor = "x" and it showed up properly.
I'm creating a Dash webapp where i have a real-time plotly chart. This chart gets updated every second. I would like to add to my X axis time instead of a fixed value. I tried setting tickvals= to dt.now but it doesn't work, since tickvals needs an array. Any advice?
def gen_wind_speed(interval):
trace = Scatter(
y=df['num'],
line=Line(
color='#42C4F7'
),
)
layout = Layout(
height=450,
xaxis=dict(
showgrid=False,
showline=False,
zeroline=False,
fixedrange=True,
tickvals= dt.now
),
margin=Margin(
t=45,
l=50,
r=50
)
)
return Figure(data=[trace], layout=layout)