Home > database >  Barplot based on coloured sectors
Barplot based on coloured sectors

Time:01-16

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()

What code creates

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? Target plot

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()

enter image description here

  • Related