I have made a plot using plotly express line. Now I want to edit the x axis ticks, so that they are 1st day of every month, meaning I would get 1 Jan 1 Feb 1 Mar 1 Apr. How can I achieve that? I was trying with
fig = px.line(df, x='date',y='value',color='transportation')
fig.update_layout(
xaxis_tickformat = '%d %b',
xaxis=dict(
tickmode = 'array',
tickvals = ['2020-02-01'],
ticktext = ['1 Feb'])
But tickvals and ticktext do not change.
Related
how not to show mid of the 12pm on the chard. I want days only.
Here is the dataset from the chart https://easyupload.io/gxfiq1
df_combined = df_combined.sort_values(by='sold_date', ascending=True)
df_smt = df_combined.loc[df_combined['model'] == 'Adapt'].groupby('date').agg({'price': 'sum', 'sold_date': 'count'}).reset_index()
fig = px.line(df_smt, x='date', y='price', title='Adapt')
fig.show()
Looks like you are trying to update the "x-tick" labels. The plotly documentation has some information on how to do this (https://plotly.com/python/tick-formatting/)
Something like
fig.update_layout(
xaxis_tickformat = '%b %d %Y',
)
should format the x-ticks as month (%b), day (%d), year (%Y).
You can see more information on formatting options here (https://github.com/d3/d3-time-format/blob/main/README.md)
This question already has answers here:
How to show all x-axis tick values in Plotly?
(3 answers)
Closed 4 months ago.
I need to change the x-axis of this chart. The dataframe has time data per day, from 2012 to October 2022. I want to be able to see in the xaxis all the years and the chart shows me only every 2 years.
import plotly.express as px
fig = px.line(data_SPY, y=['Close'], line_shape='linear', color_discrete_sequence=["#930435"],
labels={'value': "Precio", 'Date': "Fecha"})
fig.update_layout(
showlegend=False,
title= 'Precio SPY ETF',
font_color= "#000000",
font_family="Tahoma",
xaxis = dict(
tickangle = 0,
ticklabelstep=1,
showgrid=True,
),
yaxis = dict(
showgrid=True
),
legend = dict(
orientation='v'
),
paper_bgcolor='#FFFFFF'
)
fig.show(renderer="iframe")
enter image description here
You'd need to specify the dtick.
fig.update_xaxes(dtick='Y1')
Having checked through StackOverflow for a possible solution to the above error that I encountered, I found some solutions which were not able to solve this particular issue.
The following image shows the error encountered and the undesirable figure obtained while trying to plot multiple axes on a figure:
This is an image of the expected output:
Also, the data I am working with can be found at: https://drive.google.com/file/d/1ZxD3BwpJfEVMWPoxu-aom_wXawMfSywk/view?usp=sharing
Below is the set of codes that I have scripted, and I seem to have hit a roadblock. I would appreciate any help that will guide me to achieve the expected output #image2.
import matplotlib.dates as md
# Date already in DateTime index
dk1 = data.loc["1991":"2000"] # selects all rows from 1991 - 2000
dk2 = data.loc["2001":"2010"] # selects all rows from 2001 - 2010
dk3 = data.loc["2011":"2020"] # selects all rows from 2011 - 2020
plt.rcParams['font.size'] = 18
fig = plt.figure(figsize=(20,15)) # Create a figure for the plot
# Add three axes to the plots
ax1 = plt.subplot(111)
ax2 = plt.subplot(212)
ax3 = plt.subplot(313)
# Plot the data
ax1.plot(dk1.TX, label = 'Max temp')
ax2.plot(dk2.TX, label = 'Max temp')
ax3.plot(dk3.TX, label = 'Max temp')
# Set the title
ax1.set_title("Station: Ikeja, 1991~2000, tmax\n")
ax2.set_title("Station: Ikeja, 2001~2010, tmax\n")
ax3.set_title("Station: Ikeja, 2011~2020, tmax\n")
ax1.legend() # Plot the legend for first axes
ax2.legend() # Plot the legend for second axes
ax3.legend() # Plot the legend for third axes
# Set the x- and y-axis label
ax1.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax1.set_xlabel('\nYear') # Set the X-Axis label
ax2.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax2.set_xlabel('\nYear') # Set the X-Axis label
ax3.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax3.set_xlabel('\nYear') # Set the X-Axis label
# formatted X axis in Year
ax1.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax1.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax2.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax2.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax3.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax3.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
# Set the limits (range) of the X-Axis
ax1.set_xlim([pd.to_datetime('1991 1 1', format = format),
pd.to_datetime('2000 12 31', format = format)])
ax2.set_xlim([pd.to_datetime('2001 1 1', format = format),
pd.to_datetime('2010 12 31', format = format)])
ax3.set_xlim([pd.to_datetime('2010 1 1', format = format),
pd.to_datetime('2020 12 31', format = format)])
plt.show()
The error is due to the argument passed to matplotlib.pyplot.subplot: since you want three plot on three different rows (same column), then you should use:
ax1 = plt.subplot(3, 1, 1)
ax2 = plt.subplot(3, 1, 2)
ax3 = plt.subplot(3, 1, 3)
In any case, your code need some changes in order to achieve the results you want.
First of all it is wise to convert 'Time' column from str type to datetime:
data['time'] = pd.to_datetime(data['time'], format = '%m/%d/%Y')
Then, since you need to filter data based on year, you should create a column with the year:
data['year'] = data['time'].dt.year
At this point you can filter your data based on the 'year' column:
dk1 = data[(data['year'] >= 1991) & (data['year'] <= 2000)] # selects all rows from 1991 - 2000
dk2 = data[(data['year'] >= 2001) & (data['year'] <= 2010)] # selects all rows from 2001 - 2010
dk3 = data[(data['year'] >= 2011) & (data['year'] <= 2020)] # selects all rows from 2011 - 2020
As already mentioned, you should create the subplots in the proper way:
ax1 = plt.subplot(3, 1, 1)
ax2 = plt.subplot(3, 1, 2)
ax3 = plt.subplot(3, 1, 3)
Finally, pay attention to the set_xlim code: format is a special keyword in python:
ax1.set_xlim([pd.to_datetime('1991 1 1', format = '%Y %m %d'),
pd.to_datetime('2000 12 31', format = '%Y %m %d')])
ax2.set_xlim([pd.to_datetime('2001 1 1', format = '%Y %m %d'),
pd.to_datetime('2010 12 31', format = '%Y %m %d')])
ax3.set_xlim([pd.to_datetime('2010 1 1', format = '%Y %m %d'),
pd.to_datetime('2020 12 31', format = '%Y %m %d')])
Complete code
import matplotlib.dates as md
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv(r'data/max_temp.csv')
data['time'] = pd.to_datetime(data['time'], format = '%m/%d/%Y')
data['year'] = data['time'].dt.year
# # Date already in DateTime index
dk1 = data[(data['year'] >= 1991) & (data['year'] <= 2000)] # selects all rows from 1991 - 2000
dk2 = data[(data['year'] >= 2001) & (data['year'] <= 2010)] # selects all rows from 2001 - 2010
dk3 = data[(data['year'] >= 2011) & (data['year'] <= 2020)] # selects all rows from 2011 - 2020
plt.rcParams['font.size'] = 18
fig = plt.figure(figsize=(20,15)) # Create a figure for the plot
# Add three axes to the plots
ax1 = plt.subplot(3, 1, 1)
ax2 = plt.subplot(3, 1, 2)
ax3 = plt.subplot(3, 1, 3)
# Plot the data
ax1.plot(dk1.time, dk1.TX, label = 'Max temp')
ax2.plot(dk2.time, dk2.TX, label = 'Max temp')
ax3.plot(dk3.time, dk3.TX, label = 'Max temp')
# Set the title
ax1.set_title("Station: Ikeja, 1991~2000, tmax\n")
ax2.set_title("Station: Ikeja, 2001~2010, tmax\n")
ax3.set_title("Station: Ikeja, 2011~2020, tmax\n")
ax1.legend() # Plot the legend for first axes
ax2.legend() # Plot the legend for second axes
ax3.legend() # Plot the legend for third axes
# Set the x- and y-axis label
ax1.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax1.set_xlabel('\nYear') # Set the X-Axis label
ax2.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax2.set_xlabel('\nYear') # Set the X-Axis label
ax3.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax3.set_xlabel('\nYear') # Set the X-Axis label
# formatted X axis in Year
ax1.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax1.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax2.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax2.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax3.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax3.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
# Set the limits (range) of the X-Axis
ax1.set_xlim([pd.to_datetime('1991 1 1', format = '%Y %m %d'),
pd.to_datetime('2000 12 31', format = '%Y %m %d')])
ax2.set_xlim([pd.to_datetime('2001 1 1', format = '%Y %m %d'),
pd.to_datetime('2010 12 31', format = '%Y %m %d')])
ax3.set_xlim([pd.to_datetime('2010 1 1', format = '%Y %m %d'),
pd.to_datetime('2020 12 31', format = '%Y %m %d')])
plt.show()
I'm trying to display a horizontal bar chart with dates on the x-axis, but can't seem a way to do that although the x-values are dates of type string. As you can see below, the numbers that occur as ticklabels have to be a summation of some sort, but I'm not sure exactly what. How can you change the example below to get dates as ticklabels?
Plot 1:
Code:
# imports
import numpy as np
import pandas as pd
import plotly.express as px
from datetime import datetime
# data
np.random.seed(1)
cols=list('ABCDE')
df = pd.DataFrame(np.random.randint(0,2,size=(5, len(cols))), columns=cols)
drng=pd.date_range(datetime(2020, 1, 1).strftime('%Y-%m-%d'), periods=df.shape[0]).tolist()
df['date']=[d.strftime('%Y-%m-%d') for d in drng]
dfm=pd.melt(df, id_vars=['date'], value_vars=df.columns[:-1])
# plotly express
fig = px.bar(dfm, x="date", y="variable", color='value', orientation='h',
hover_data=["date"],
height=400,
color_continuous_scale=['blue', 'teal'],
title='Custom date ticklabels for vertical bar plot',
template='plotly_white',
)
fig.update_traces(showlegend=False)
fig.update(layout_coloraxis_showscale=False)
fig.show()
What I've tried:
I've tried different combinations for tickmode, tickvals and ticktext for xaxis=dict() in fig.update_layout, alas with completely useless results.
Attempt 2: ticktext
Set tickvals=df['date']
fig.update_layout(yaxis=dict(title=''),
xaxis=dict(title='',
gridcolor='grey',
#tickmode= 'array',
#tickmode= 'linear',
#tick0= 2220,
#dtick=200,
#tickvals= [2020, 2040],
ticktext = df['date'])
)
Plot 2:
Same as before:
Attempt 3: ticktext & dtick
To my amazement, setting dtick to some arbitrary value gives you the plot below.
fig.update_layout(yaxis=dict(title=''),
xaxis=dict(title='',
gridcolor='grey',
#tickmode= 'array',
#tickmode= 'linear',
tick0= 2050,
dtick=2,
#tickvals= [2020, 2040],
ticktext = df['date'])
)
Plot 3:
Still amazingly useless, but now the ticks at least looks like dates, although we're looking at a value that represents a timestamp in 2008 and the source data is 2020...
Attempt 4: tickvals and ticktext
fig.update_layout(yaxis=dict(title=''),
xaxis=dict(title='',
gridcolor='grey',
#tickmode= 'array',
#tickmode= 'linear',
tick0= 2050,
#dtick=2,
tickvals= [2050, 2100, 2150, 2200],
ticktext = df['date'])
)
Plot 4:
From the looks of if, this is exactly what I'm looking for:
But this is equally useless like the other attempts, since we have to specify tickvals= [2050, 2100, 2150, 2200]. If we change the period, these values will have to be re-specified, and that's not very flexible. Of course, if we somehow could retrieve the default tickvalues used by plotly, we could easily replace them with the dates in the dataset. But that seems to still be impossible according to the answer to the post Plotly: How to retrieve values for major ticks and gridlines?
I'm at a complete loss here, and baffled by the uselessness of my attempts, so any other suggestions would be great!
You must activate tickmode to 'array' and then define tickvals and ticktext, like:
tickmode = 'array',
tickvals = [2050, 2100, 2150, 2200],
ticktext = df['date'])
I have my x-axis values in this format : ['May 23 2018 06:31:52 GMT', 'May 23 2018 06:32:02 GMT', 'May 23 2018 06:32:12 GMT', 'May 23 2018 06:32:22 GMT', 'May 23 2018 06:32:32 GMT']
and corresponding values for the y-axis which are some numbers.
But when I am plotting these using plotly , x-axis show only part of the date (May 23 2018) for each point. Time for each point is not shown.
I tried setting up tickformat also in layout, but it does not seems to work.
layout = go.Layout(
title=field+ "_its diff_value chart",
xaxis = dict(
tickformat = '%b %d %Y %H:%M:%S'
)
)
any help is appreciated.
This is the screenshot of the graph made.
Try converting your x-values to datetime objects
Then tell plotly to use a fixed tick distance
import random
import datetime
import plotly
plotly.offline.init_notebook_mode()
x = [datetime.datetime.now()]
for d in range(100):
x.append(x[0] + datetime.timedelta(d))
y = [random.random() for _ in x]
scatter = plotly.graph_objs.Scatter(x=x, y=y)
layout = plotly.graph_objs.Layout(xaxis={'type': 'date',
'tick0': x[0],
'tickmode': 'linear',
'dtick': 86400000.0 * 14}) # 14 days
fig = plotly.graph_objs.Figure(data=[scatter], layout=layout)
plotly.offline.iplot(fig)
To skip inconsistent time series, add this before plotting the plotly chart
fig.update_xaxes(
rangebreaks=[
dict(bounds=['2018-05-23 06:31:52','2018-05-23 06:32:02']),
dict(bounds=['2018-05-23 06:32:02','2018-05-23 06:32:12']),
dict(bounds=['2018-05-23 06:32:12','2018-05-23 06:32:22']),
dict(bounds=['2018-05-23 06:32:22','2018-05-23 06:32:32'])
]
)