I am creating a bar plot where the colour of the bar is proportional to the value. However, is it possible to break down the bar into colour sectors? See below what I have and what I mean:
import pandas as pd
import plotly.express as px
df = px.data.wind()
df_test = df[df["strength"]=='0-1']
fig=px.bar_polar(df_test,r='frequency',theta='direction', color='frequency',color_continuous_scale='YlGn')
fig.show()
Below is what I want to achieve. Is it possible to have the polar sections instead of the actuar bars? Maybe at least add the horizontal axis to the bars? Or is there any other plotly chart type for this?
CodePudding user response:
You can create linearly spaced arrays for each direction in df_test
. Currently df_test
looks like the following:
direction strength frequency
0 N 0-1 0.5
1 NNE 0-1 0.6
2 NE 0-1 0.5
3 ENE 0-1 0.4
4 E 0-1 0.4
5 ESE 0-1 0.3
6 SE 0-1 0.4
7 SSE 0-1 0.4
8 S 0-1 0.6
9 SSW 0-1 0.4
10 SW 0-1 0.5
11 WSW 0-1 0.6
12 W 0-1 0.6
13 WNW 0-1 0.5
14 NW 0-1 0.4
15 NNW 0-1 0.1
What we want is for each direction to have linearly spaced frequencies between 0.1 and the ending frequency value in df_test for that particular direction, such as the following:
direction strength frequency
0 N 0-1 0.1
1 N 0-1 0.2
2 N 0-1 0.3
3 N 0-1 0.4
4 N 0-1 0.5
5 NNE 0-1 0.1
...
We can perform a groupby
on direction
for df_test, then use np.arange
to obtain the linearly spaced array for that particular direction, and build the resulting dataframe using pd.concat
. Then we can sort the new DataFrame so the directions are in the correct order (as this is the format that px.bar_polar expects).
import numpy as np
import pandas as pd
import plotly.express as px
df = px.data.wind()
df_test = df[df["strength"]=='0-1']
df_test_sectors = pd.DataFrame(columns=df_test.columns)
## this only works if each group has one row
for direction, df_direction in df_test.groupby('direction'):
frequency_stop = df_direction['frequency'].tolist()[0]
frequencies = np.arange(0.1, frequency_stop 0.1, 0.1)
df_sector = pd.DataFrame({
'direction': [direction]*len(frequencies),
'strength': ['0-1']*len(frequencies),
'frequency': frequencies
})
df_test_sectors = pd.concat([df_test_sectors, df_sector])
df_test_sectors = df_test_sectors.reset_index(drop=True)
df_test_sectors['direction'] = pd.Categorical(
df_test_sectors['direction'],
df_test.direction.tolist() #sort the directions into the same order as those in df_test
)
df_test_sectors['frequency'] = df_test_sectors['frequency'].astype(float)
df_test_sectors = df_test_sectors.sort_values(['direction', 'frequency'])
fig = px.bar_polar(df_test_sectors, r='frequency', theta='direction', color='frequency', color_continuous_scale='YlGn')
fig.show()