Is it possible to generate a clock chart using Plotly? - python

I'm developing a dataviz project and I came across the report generated by Last.FM, in which there is a clock chart to represent the distribution of records by hours.
The chart in question is this:
It is an interactive graph, so I tried to use the Plotly library to try to replicate the chart, but without success.
Is there any way to replicate this in Plotly? Here are the data I need to represent
listeningHour = df.hour.value_counts().rename_axis('hour').reset_index(name='counts')
listeningHour
hour counts
0 17 16874
1 18 16703
2 16 14741
3 19 14525
4 23 14440
5 22 13455
6 20 13119
7 21 12766
8 14 11605
9 13 11575
10 15 11491
11 0 10220
12 12 7793
13 1 6057
14 9 3774
15 11 3476
16 10 1674
17 8 1626
18 2 1519
19 3 588
20 6 500
21 7 163
22 4 157
23 5 26

The graph provided by Plotly is a polar bar chart. I have written a code using it with your data. At the time of my research, there does not seem to be a way to place the ticks inside the doughnut. The point of the code is to start at 0:00 in the direction of the angle axis. The clock display is a list of 24 tick places with an empty string and a string every 6 hours. The angle grid is aligned with the center of the bar chart.
import plotly.graph_objects as go
r = df['counts'].tolist()
theta = np.arange(7.5,368,15)
width = [15]*24
ticktexts = [f'$\large{i}$' if i % 6 == 0 else '' for i in np.arange(24)]
fig = go.Figure(go.Barpolar(
r=r,
theta=theta,
width=width,
marker_color=df['counts'],
marker_colorscale='Blues',
marker_line_color="white",
marker_line_width=2,
opacity=0.8
))
fig.update_layout(
template=None,
polar=dict(
hole=0.4,
bgcolor='rgb(223, 223,223)',
radialaxis=dict(
showticklabels=False,
ticks='',
linewidth=2,
linecolor='white',
showgrid=False,
),
angularaxis=dict(
tickvals=np.arange(0,360,15),
ticktext=ticktexts,
showline=True,
direction='clockwise',
period=24,
linecolor='white',
gridcolor='white',
showticklabels=True,
ticks=''
)
)
)
fig.show()

Related

python: cumulative density plot

I have the following dataframe:
df =
Time_to_event event
0 0 days 443
1 1 days 226
2 2 days 162
3 3 days 72
4 4 days 55
5 5 days 30
6 6 days 36
7 7 days 18
8 8 days 15
9 9 days 14
10 10 days 21
11 11 days 13
12 12 days 10
13 13 days 10
14 14 days 8
I want to produce a cumulative density plot of the sum of the events per days. For example 0 days 443, 1 days = 443 + 226 etc.
I am currently trying this code:
stat = "count" # or proportion
sns.histplot(df, stat=stat, cumulative=True, alpha=.4)
but I come up with a pretty terrible plot:
If I could also come up with a line instead of bars that would be awesome!
You can try a combo of pandas.Series.cumsum and seaborn.lineplot :
df["cumsum"] = df["event"].cumsum()
plt.figure(figsize=(6,4))
sns.lineplot(x="Time_to_event", y="cumsum", data=df);
Output :
I think what you are looking for your plot values is:
xvalues=df["Time_to_event"]
yvalues=df["event"].cumsum()
The code could look like this:
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_csv("test.txt")
print(df.columns)
print(df)
plt.bar(df["Time_to_event"],df["event"].cumsum())
# replace plt.bar with plt.plot for a plotted diagram
plt.show()

Add x-axis to matplotlib with multiple y-axis line chart

How do I add the x-axis(Month) to a simple Matplotlib
My Dataset:
Month Views CMA30
0 11 24662 24662.000000
1 11 2420 13541.000000
2 11 11318 12800.000000
3 11 8529 11732.250000
4 10 78861 25158.000000
5 10 1281 21178.500000
6 10 22701 21396.000000
7 10 17088 20857.500000
This is my code:
df[['Views', 'CMA30']].plot(label='Views', figsize=(5, 5))
This is giving me Views and CMA30 on the y-axis. How do I add Month(1-12) on the x-axis?
If you average the values per month, then try groupby/mean:
df.groupby('Month')[['Views','CMA30']].mean().plot(label='Views', figsize=(5, 5))

How to add up more data in an existing plotly graph?

I have successfully plotted the below data using plotly from an Excel file.
Here is my code:
file_loc1 = "AgeGroupData_time_to_treatment.xlsx"
df_centroid_CoordNew = pd.read_excel(file_loc1, index_col=None, na_values=['NA'], usecols="C:D,AB")
df_centroid_CoordNew.head()
df_centroid_Coord['Ambulance_Treatment_Time'] = df_centroid_Coord ['Base_TT']
fig = px.scatter(df_centroid_Coord, x="x", y="y",
title="Southern Region Centroids",
color='Ambulance_Treatment_Time',
hover_name="KnNamn",
hover_data= ['Ambulance_Treatment_Time', "TotPop"],
log_x=True, size_max=60,
color_continuous_scale='Reds', range_color=(0.5,2), width=1250, height=1000)
fig.update_traces(marker={'size': 8, 'symbol': 1})
#fig.update_traces(marker={'symbol': 1})
fig.update_layout(paper_bgcolor="LightSteelBlue")
fig.show()
The shapes of the plotted data points are square.
Here is output of my code:
Now, I want to plot more data points in circle or any shapes on the same plotly graph by reading an excel file. Please have a look at the data below.
How I can add up the new data to an existing graph in plotly?
Map data with total population and treatment time (Base_TT):
ID KnNamn x y TotPop Base_TT
1 2 Växjö 14.662290 57.027520 9 1.599971
2 3 Bromölla 14.494072 56.065635 264 1.307165
3 4 Trelleborg 13.219968 55.478675 40 1.411554
4 5 Tomelilla 14.005013 55.721209 6 1.968138
5 6 Halmstad 12.737361 56.710973 386 1.309849
6 7 Alvesta 14.566685 56.748729 47 1.719117
7 8 Laholm 13.241388 56.413591 0 2.000620
8 9 Tingsryd 14.943081 56.542837 16 1.668725
9 10 Sölvesborg 14.574474 56.056953 1147 1.266862
10 11 Halmstad 13.068009 56.635666 38 1.589239
11 12 Tingsryd 14.699642 56.479597 3 1.960050
12 13 Vellinge 13.029769 55.484749 61 1.254957
13 14 Örkelljunga 13.169010 56.232819 12 1.429789
14 15 Svalöv 13.059068 55.853696 26 1.553722
15 16 Sjöbo 13.738205 55.601936 6 1.326429
16 17 Hässleholm 13.729872 56.347672 13 1.709021
17 18 Olofström 14.588037 56.290604 6 1.444833
18 19 Eslöv 13.168712 55.900311 3 1.527547
19 20 Ronneby 15.024222 56.273317 3 1.692005
20 21 Ängelholm 12.910101 56.246689 19 1.090544
Ambulance Data:
ID Ambulance station name Longtitude Latitude
0 1 Älmhult 14.128734 56.547992
1 2 Ängelholm 12.870739 56.242114
2 3 Alvesta 14.549503 56.920740
3 4 Östra Ljungby 13.057450 56.188099
4 5 Broby 14.080958 56.254481
5 6 Bromölla 14.466869 56.072272
6 7 Förslöv 12.814913 56.350098
7 9 Hässleholm 13.778234 56.161536
8 10 Höganäs 12.556995 56.206016
9 11 Hörby 13.643265 55.849811
10 12 Halmstad, Väster 12.819960 56.674306
11 13 Halmstad, Öster 12.882289 56.676871
12 14 Helsingborg 12.738642 56.084708
13 15 Hyltebruk 13.238277 56.993058
14 16 Karlshamn 14.854022 56.186596
15 17 Karlskrona 15.606300 56.183054
16 18 Kristianstad 14.171371 56.031201
17 20 Löddeköpinge 12.995037 55.766946
18 21 Laholm 13.033763 56.498955
19 22 Landskrona 12.867245 55.872659
20 23 Lenhovda 15.283913 57.001953
21 24 Lessebo 15.267357 56.756860
22 25 Ljungby 13.935399 56.835023
23 26 Lund 13.226607 55.695212
24 27 Markaryd 13.591491 56.452057
25 28 Olofström 14.545848 56.272221
26 29 Osby 13.983674 56.384833
27 30 Perstorp 13.388304 56.130752
28 31 Ronneby 15.280554 56.211863
29 32 Sölvesborg 14.570503 56.052113
30 33 Simrishamn 14.338632 55.552765
Merged Dataset for plotting
KnNamn x y TotPop Base_TT Ambulance station name Longtitude Latitude
Växjö 14.66229 57.02752 9 1.599971 Ängelholm 12.87074 56.24211
Bromölla 14.49407 56.06564 264 1.307165 Alvesta 14.5495 56.92074
Trelleborg 13.21997 55.47868 40 1.411554 Östra Ljungby 13.05745 56.1881
Tomelilla 14.00501 55.72121 6 1.968138 Broby 14.08096 56.25448
Halmstad 12.73736 56.71097 386 1.309849
Alvesta 14.56669 56.74873 47 1.719117
Laholm 13.24139 56.41359 0 2.00062
Tingsryd 14.94308 56.54284 16 1.668725
If the data is the same but the column names are different, aligning to either column name is fine for the data for the chart.
Add a graph with a graph object by reusing the graph data created with plotly.express. First I added a chart that was already completed, then a chart with latitude and longitude. Station names and locations are drawn using scatterplot markers and text mode.
df_station.rename(columns={'Longtitude':'x', 'Latitude':'y'}, inplace=True)
import plotly.express as px
import plotly.graph_objects as go
df_centroid_Coord['Ambulance_Treatment_Time'] = df_centroid_Coord ['Base_TT']
sca = px.scatter(df_centroid_Coord, x="x", y="y",
title="Southern Region Centroids",
color='Ambulance_Treatment_Time',
hover_name="KnNamn",
#hover_data= ['Ambulance_Treatment_Time', "TotPop"],
log_x=True,
size_max=60,
color_continuous_scale='Reds',
range_color=(0.5,2),
)
sca.update_traces(marker={'size': 8, 'symbol': 1})
fig = go.Figure()
fig.add_trace(go.Scatter(sca.data[0]))
fig.add_trace(go.Scatter(x=df_station['x'],
y=df_station['y'],
mode='markers+text',
text=df_station['Ambulance station name'],
textposition='top center',
showlegend=False,
marker=dict(
size=5,
symbol=2,
color='blue'
)
)
)
#fig.update_traces(marker={'symbol': 1})
fig.update_layout(width=625, height=500, paper_bgcolor="LightSteelBlue")
fig.show()

Seaborn figure with multiple axis (year) and month on x-axis

I try to become warm with seaborn. I want to create one or both of that figures (bar plot & line plot). You see 12 months on the X-axis and 3 years each one with its own line or bar color.
That is the data creating script including the data in comments.
#!/usr/bin/env python3
import random as rd
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
rd.seed(0)
a = pd.DataFrame({
'Y': [2016]*12 + [2017]*12 + [2018]*12,
'M': list(range(1, 13)) * 3,
'n': rd.choices(range(100), k=36)
})
print(a)
# Y M n
# 0 2016 1 84
# 1 2016 2 75
# 2 2016 3 42
# ...
# 21 2017 10 72
# 22 2017 11 89
# 23 2017 12 68
# 24 2018 1 47
# 25 2018 2 10
# ...
# 34 2018 11 54
# 35 2018 12 1
b = a.pivot_table(columns='M', index='Y')
print(b)
# n
# M 1 2 3 4 5 6 7 8 9 10 11 12
# Y
# 2016 84 75 42 25 51 40 78 30 47 58 90 50
# 2017 28 75 61 25 90 98 81 90 31 72 89 68
# 2018 47 10 43 61 91 96 47 86 26 80 54 1
I'm even not sure which form (a or b or something elese) of a dataframe I should use here.
What I tried
I assume in seaboarn speech it is a countplot() I want. Maybe I am wrong?
>>> sns.countplot(data=a)
<AxesSubplot:ylabel='count'>
>>> plt.show()
The result is senseless
I don't know how I could add the pivoted dataframe b to seaborn.
You could do the first plot with a relplot, using hue as a categorical grouping variable:
sns.relplot(data=a, x='M', y='n', hue='Y', kind='line')
I'd use these colour and size settings to make it more similar to the plot you wanted:
sns.relplot(data=a, x='M', y='n', hue='Y', kind='line', palette='pastel', height=3, aspect=3)
The equivalent axes-level code would be sns.lineplot(data=a, x='M', y='n', hue='Y', palette='pastel')
Your second can be done with catplot:
sns.catplot(kind='bar', data=a, x='M', y='n', hue='Y')
Or the axes-level function sns.barplot. In that case let's move the default legend location:
sns.barplot(data=a, x='M', y='n', hue='Y')
plt.legend(bbox_to_anchor=(1.05, 1))

How to plot small floating numbers properly

How to plot the set of numbers like (first column is x-axis, second column is y-axis):
1 3.4335e-14
2 5.8945e-28
3 6.7462e-42
4 5.7908e-56
5 3.9765e-70
6 2.2756e-84
7 1.1162e-98
8 4.7904e-113
9 1.8275e-127
10 6.2749e-142
11 1.9586e-156
12 5.6041e-171
13 1.4801e-185
14 3.6300e-200
15 8.3091e-215
16 1.7831e-229
17 3.6013e-244
18 6.8694e-259
19 1.2414e-273
For now I get:
And I can't figure out how to make it properly. It means no flat line from 2 to the end and correct y-axis values. I read these values from the file with:
x_values.append(line.split(' ')[0])
y_values.append(float(line.split(' ')[1]))
You may wish to switch the yscale to "log" scale, e.g.:
import matplotlib.ticker as mtick
_,ax = plt.subplots()
plt.plot(x,y)
plt.xticks(x)
plt.yscale("log")
ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'));

Categories

Resources