Python (Bokeh) : How do i plot a line graph by using my CSV values and converting them to my outcome?
Question:
I have a CSV File with columns below:
Time Format being Month/Date/Year Hour:Minutes
Time
Event
Speed
1/30/2022 17:23
Speeding
50
1/28/2022 18:22
Speeding
20
1/27/2022 22:00
Speeding
30
1/26/2022 23:23
Speeding
40
1/27/2022 22:00
Stopping
10
1/26/2022 23:23
Stopping
10
-With the new codes my graph, will show the dates below, however i am trying to have it plot against the hours instead. This is because i am trying to show the correlation between the speed within a day to see which period of the day have higher speed.
New Codes:
import pandas as pd
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, HoverTool
output_file('Speed.html') # output for average speed graph
file = 'C:/Users/oof/Desktop/route.csv' # read csv file
df = pd.read_csv(file) # import data to pandas dataframe
df['Time'] = pd.to_datetime(df['Time'], format='%m/%d/%Y %H:%M').dt.time
grouped_by_time = df.groupby('Time')[['Speed']].mean()
print(grouped_by_time)
source = ColumnDataSource(grouped_by_time)
p1 = figure(x_axis_type='datetime')
p1.line(x='Time', y='Speed', line_width=2, source=source)
p1.title.text = 'Average Speed in a Day'
p1.yaxis.axis_label = 'Average Speed'
p1.xaxis.axis_label = '24-Hour'
TOOLTIP1 = [("Time", "@Time{%H:%M}"),
("Average Speed: ", "@Speed")]
p1.add_tools(HoverTool(tooltips=TOOLTIP1, formatters={"@Time": "datetime"}, mode='vline'))
show(p1)
Answers:
Hello and Welcome on SO @WJstudent,
you can convert date values to a datetime object with pandas using pd.to_datetime
.
To group only by time
and not by datetime
, I dropped the date information and keept the time unsing pd.Timedstamp.dt.time
.
This datetimes can be handled very well by bokeh
. To profit from the default formatting use x_axis_type='datetime'
in the definition of your figure
. The formatter is set to %H:%M
to show only hours and minutes.
The sultion below uses StringIO to load the data. This section can be removed, when you use the path to your CSV-file.
The bokeh figure itself gets two lines in blue and red (red is the mean).
Code
from io import StringIO
import pandas as pd
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.plotting import figure, show, output_notebook
output_notebook()
# here was a typo in your example data with the timestamp 1/28/2022 18.22
data = """Time Event Speed
1/30/2022 00:00 Speeding 50
1/30/2022 17:23 Speeding 50
1/28/2022 18:22 Speeding 20
1/27/2022 22:00 Speeding 30
1/26/2022 23:23 Speeding 40
1/27/2022 22:00 Stopping 10
1/26/2022 23:23 Stopping 10"""
# data handling with pandas
df = pd.read_csv(StringIO(data), sep='ss+', engine='python')
df['Time'] = pd.to_datetime(df['Time'], format='%m/%d/%Y %H:%M').dt.time
grouped_by_time = df.groupby('Time')[['Speed']].mean()
source = ColumnDataSource(grouped_by_time)
p = figure(x_axis_type='datetime', width=300, height=300)
p.line(x='Time', y='Speed', line_width=2, source=source)
p.title.text = 'Average Speed For Days'
p.yaxis.axis_label = 'Average Speed'
p.xaxis.axis_label = 'Dates'
p.xaxis.major_label_overrides = {0: '0h', 24*60*60*1000: '24h'} # this ovverrides hard by hand -- 24 hours in milliseconds
TOOLTIP = [("Time", "@Time{%H:%M}"),
("Average Speed", "@Speed")]
p.add_tools(HoverTool(tooltips=TOOLTIP, formatters={"@Time": "datetime"}, mode='vline'))
show(p)
Result
Further reading
- See the section in the first steps guide about enabling datetime axes.
- Check out thr bokeh gallary
- Check out the bokeh example page and explicit the datetime axis example.
I have a CSV File with columns below:
Time Format being Month/Date/Year Hour:Minutes
Time | Event | Speed |
---|---|---|
1/30/2022 17:23 | Speeding | 50 |
1/28/2022 18:22 | Speeding | 20 |
1/27/2022 22:00 | Speeding | 30 |
1/26/2022 23:23 | Speeding | 40 |
1/27/2022 22:00 | Stopping | 10 |
1/26/2022 23:23 | Stopping | 10 |
-With the new codes my graph, will show the dates below, however i am trying to have it plot against the hours instead. This is because i am trying to show the correlation between the speed within a day to see which period of the day have higher speed.
New Codes:
import pandas as pd
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, HoverTool
output_file('Speed.html') # output for average speed graph
file = 'C:/Users/oof/Desktop/route.csv' # read csv file
df = pd.read_csv(file) # import data to pandas dataframe
df['Time'] = pd.to_datetime(df['Time'], format='%m/%d/%Y %H:%M').dt.time
grouped_by_time = df.groupby('Time')[['Speed']].mean()
print(grouped_by_time)
source = ColumnDataSource(grouped_by_time)
p1 = figure(x_axis_type='datetime')
p1.line(x='Time', y='Speed', line_width=2, source=source)
p1.title.text = 'Average Speed in a Day'
p1.yaxis.axis_label = 'Average Speed'
p1.xaxis.axis_label = '24-Hour'
TOOLTIP1 = [("Time", "@Time{%H:%M}"),
("Average Speed: ", "@Speed")]
p1.add_tools(HoverTool(tooltips=TOOLTIP1, formatters={"@Time": "datetime"}, mode='vline'))
show(p1)
Hello and Welcome on SO @WJstudent,
you can convert date values to a datetime object with pandas using pd.to_datetime
.
To group only by time
and not by datetime
, I dropped the date information and keept the time unsing pd.Timedstamp.dt.time
.
This datetimes can be handled very well by bokeh
. To profit from the default formatting use x_axis_type='datetime'
in the definition of your figure
. The formatter is set to %H:%M
to show only hours and minutes.
The sultion below uses StringIO to load the data. This section can be removed, when you use the path to your CSV-file.
The bokeh figure itself gets two lines in blue and red (red is the mean).
Code
from io import StringIO
import pandas as pd
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.plotting import figure, show, output_notebook
output_notebook()
# here was a typo in your example data with the timestamp 1/28/2022 18.22
data = """Time Event Speed
1/30/2022 00:00 Speeding 50
1/30/2022 17:23 Speeding 50
1/28/2022 18:22 Speeding 20
1/27/2022 22:00 Speeding 30
1/26/2022 23:23 Speeding 40
1/27/2022 22:00 Stopping 10
1/26/2022 23:23 Stopping 10"""
# data handling with pandas
df = pd.read_csv(StringIO(data), sep='ss+', engine='python')
df['Time'] = pd.to_datetime(df['Time'], format='%m/%d/%Y %H:%M').dt.time
grouped_by_time = df.groupby('Time')[['Speed']].mean()
source = ColumnDataSource(grouped_by_time)
p = figure(x_axis_type='datetime', width=300, height=300)
p.line(x='Time', y='Speed', line_width=2, source=source)
p.title.text = 'Average Speed For Days'
p.yaxis.axis_label = 'Average Speed'
p.xaxis.axis_label = 'Dates'
p.xaxis.major_label_overrides = {0: '0h', 24*60*60*1000: '24h'} # this ovverrides hard by hand -- 24 hours in milliseconds
TOOLTIP = [("Time", "@Time{%H:%M}"),
("Average Speed", "@Speed")]
p.add_tools(HoverTool(tooltips=TOOLTIP, formatters={"@Time": "datetime"}, mode='vline'))
show(p)
Result
Further reading
- See the section in the first steps guide about enabling datetime axes.
- Check out thr bokeh gallary
- Check out the bokeh example page and explicit the datetime axis example.