Count based on two sub groups in Power Bi - excel

I have Data as in following table, I want to show the % of work order count over the year for each group in stacked area chart but I am struggling to get the correct %. From the below data the % of each Days Delayed group should come as 50%
Appreciate any helps.

First, create this below Measure-
group_wsie_percentage =
VAR total_count =
CALCULATE(
COUNT(your_table_name[days delayed group]),
ALLEXCEPT(
your_table_name,
your_table_name[year]
)
)
VAR total_group_count =
CALCULATE(
COUNT(your_table_name[days delayed group]),
ALLEXCEPT(
your_table_name,
your_table_name[year],
your_table_name[days delayed group]
)
)
RETURN total_group_count/total_count
Now change the type of measure as % and configure your Stacked (I used Stacked Bar chart) chart as below-
Here is the output-

Related

Displaying multiple values in Altair/Streamlit tooltips on a bar chart

My DataFrame looks similar to this:
name
reached points
Jose Laderman
13
William Kane
13
I am currently displaying the aggregated count of students reached points of an assignment on an Altair bar chart within Streamlit like this:
brush = alt.selection(type='interval', encodings=['x'])
interactive_test = alt.Chart(df_display_all).mark_bar(opacity=1, width=5).encode(
x= alt.X('reached points', scale=alt.Scale(domain=[0, maxPoints])),
y=alt.Y('count()', type='quantitative', axis=alt.Axis(tickMinStep=1), title='student count'),
).properties(width=1200)
upper = interactive_test.encode(
alt.X('reached points', sort=alt.EncodingSortField(op='count', order='ascending'), scale=alt.Scale(domain=brush, domainMin=-0.5))
)
lower = interactive_test.properties(
height=60
).add_selection(brush)
concat_distribution_interactive = alt.vconcat(upper, lower)
Which produces this output and everything looks fine
The information I want my tooltip to show is a list of students that reached the specific amounts of reached points I'm hovering over. When adding something like:
tooltip='name'
the way my bar chart seems to display values has now been altered to this
When adding something like
tooltip='reached points'
The data seems to be displayed normally but without a tooltip that gives me the necessary information. Is it possible to display tooltip data that isn't used in my x or y axis but still part of the DataFrame I'm putting into the chart?

Add custom markers to Gantt Chart in Plotly

I’m new to plotly and I’m creating a gantt chart using px.timeline. There are 3 categories of data in my dataset, a normal task with a start and end time, and two types of task where the start and end time are same. I want the normal task to be a rectangle (which is how it is being plot) and the other two tasks to have a hourglass marker and a triangle marker instead of a very thin line ?
This is how my data looks :
data = [dict(Task=’’, start=’’, end=’’, shape=’<rect, hour, tri>’)]
Sample Data :
df = [dict(Task="Job A", Start='2009-01-01', Finish='2009-01-01', shape='hourglass'),
dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15', shape='rectangle'),
dict(Task="Job C", Start='2009-05-30', Finish='2009-05-30', shape='triangle')]
Code :
fig = px.timeline(data, x_start="Start", x_end="Finish", y="Task")
fig.update_yaxes(autorange="reversed", ticklabelposition="outside left")
fig.update_layout(showlegend=False, height=2000, width=1255, margin_pad=10)
fig.show()
Example:
Sample Plot in Excel
Is there any way I can achieve this ?
Thanks !
I solved this after some hours of searching.
Split the data into three each corresponding to 3 different shapes and then plot and combine.
Create 3 individual Plots :
rect = px.timeline(rect, x_start="Start", x_end="Finish", y="Task", color="color")
dia = px.scatter(dia, x="Start", y="Task", color="color", symbol_sequence=['diamond'])
coll = px.scatter(coll, x="Start", y="Task", color="color", symbol_sequence=['hourglass'])
Update traces for individual plots if needed :
rect.update_traces(marker=dict(line=dict(width=1, color='black')))
dia.update_traces(marker=dict(size=12, line=dict(width=2)))
coll.update_traces(marker=dict(size=12, line=dict(width=2)))
Set the timeline plot's axis:
rect.update_xaxes(tickformat="%H:%M:%S.%L", tickmode='linear', dtick='120000')
rect.update_yaxes(autorange='reversed')
rect.update_layout(title=title, showlegend=False, height=2800, width=2000)
Overlay all Plots:
new_fig = go.Figure(data=rect.data + dia.data + coll.data, layout=rect.layout)
new_fig.show()

Bumbling around plotting two sets of seasonal data on the same chart

I have series of monthly inventory data since 2017.
I have a series of inventory_forecasts since Dec2018
I am trying to plot the inventory data on a monthly-seasonal basis, and then overlay the inventory_forecasts of Jan2019 through Dec2019.
The dataframe looks like:
The first way I tried to make the chart does show all the data I want, but I'm unable to control the color of the inventory_zj line. Its color seems to be dominated by the color=year(date):N of the alt.Chart I configured. It is ignoring the color='green' I pass to the mark_line()
base = alt.Chart(inv.loc['2000':].reset_index(), title=f"usa total inventory").mark_line().encode(
x='month',
y="inventory",
color="year(date):N"
)
#this ignores my 'green' color instruction, and marks it the same light blue 2019 color
joe = base.mark_line(color='green').encode(
alt.Y('inventory_zj', scale=alt.Scale(zero=False), )
)
base+joe
I tried to use a layering system, but it's not working at all -- I cannot get it to display the "joe" layer
base = alt.Chart(inv.loc['2000':].reset_index(), title=f"usa total inventory").encode(
x='month(date)'
)
doe = base.mark_line().encode(
alt.Y('inventory', scale=alt.Scale(zero=False), ),
color="year(date):N"
)
joe = base.mark_line(color="green").encode(
alt.Y('inventory_zj', scale=alt.Scale(zero=False), ),
)
#looks identical to the first example
alt.layer(
doe, joe
).resolve_scale(
y='shared'
).configure_axisLeft(labelColor='black').configure_axisRight(labelColor='green',titleColor='green')
#independent shows a second y-axis (which is different from the left y-axis) but no line
alt.layer(
doe, joe
).resolve_scale(
y='independent'
).configure_axisLeft(labelColor='black').configure_axisRight(labelColor='green',titleColor='green')
I feel like i must be trying to assemble this chart in a fundamentally wrong way. I should be able to share teh same left y-axis, have the historic data colored by its year, and have a unique color for the 2019-forecasted data. But I seem to be making a mess of it.
As mentioned in the Customizing Visualizations docs, there are multiple ways to specify things like line color, with a well-defined hierarchy: encodings override mark properties, which override top-level configurations.
In your chart, you write base.mark_point(color='green'), where base contains a color encoding which overrides the mark property. If you don't derive the layer from base (so that it does not have a color encoding), then the line will be green as you hoped. Something like this:
base = alt.Chart(inv.loc['2000':].reset_index(), title=f"usa total inventory")
inventory = base.mark_line().encode(
x='month',
y="inventory",
color="year(date):N"
)
joe = base.mark_line(color='green').encode(
x='month',
y=alt.Y('inventory_zj', scale=alt.Scale(zero=False))
)
inventory + joe

Control legend color and order when joining two charts in Altair

I am having difficulty getting the correct order for color in the legend.
I am trying to attain:
cash: blue
fixed_income: yellow
equity: red
I am charting two rows of three charts using the following dataframe 'dfl':
trade_date account owner account_type asset value sort_asset
0 2002-01-02 p2_inv p2 inv cash 0.0 0
1 2002-01-03 p2_inv p2 inv cash 0.0 0
2 2002-01-04 p2_inv p2 inv cash 0.0 0
dfl.shape (76824, 7)
I have the following code:
df_p1 = dfl[dfl['owner'] == 'p1']
df_p2 = dfl[dfl['owner'] == 'p2']
base_p1 = alt.Chart(df_p1).mark_area().encode(
x=alt.X('trade_date:T', title=""),
y=alt.Y('sum(value):Q', stack='normalize', title="Asset Allocation"),
color=alt.Color('asset:N', sort=['cash', 'fixed_income', 'equity']),
order=alt.Order('sort_asset:N', sort='ascending')
).properties(
width=120,
height=160
).facet(
column=alt.Column('account:N'),
)
base_p2 = alt.Chart(df_p2).mark_area().encode(
x=alt.X('trade_date:T', title=""),
y=alt.Y('sum(value):Q', stack='normalize', title="Asset Allocation"),
color=alt.Color('asset:N', sort=['cash', 'fixed_income', 'equity']),
order=alt.Order('sort_asset:N', sort='ascending')
).properties(
width=120,
height=160
).facet(
column=alt.Column('account:N'),
)
base_p1 & base_p2
When I run base_p1 or base_p2 by themselves, I get the correct legend. But when I join them together using & my legend and color changes to:
cash: blue
equity: yellow
fixed income: red
I also note I added in a sort_asset column in the DataFrame that I can use to sort the assets correctly, and I'm using it to ensure the stack is sorted properly.
I'm sure I'm missing something simple as I'm new to altair. What can I change in the code above to render the proper colors and orders?
This is a known bug in Altair version 2: sorted fields are not preserved in compound charts. Some details (including ideas for workarounds) are here: https://github.com/altair-viz/altair/issues/820
Altair 3.0 fixes this bug, and should be released some time in the coming week.

Daily subsets of Annual Data

I am trying to optimize an energy production process in a year, based on the hourly resolutions. The purchased electricity price from the grid has two different values based on the two times of a day; between 07:00-18:00 the price is 10, between 18:00-07:00 the price is 5.
The time sets are:
P_el electricityprice /t7*t18 10, t19*t6 5, ....../
t time /t1*t8760/
How can I create the P_el automatically, so that I don't need to write different sets by hand until the 8760th hour?
I think what you want to do here is make p_el a parameter, not a set. The following should work. (Do check that I got the timing exactly right)
set t "time" /t1*t8760/;
parameter hour(t) "hour of the day from 1 to 24";
parameter p_el(t) "electricity price";
hour(t) = mod(ord(t), 24);
p_el(t) = 5;
p_el(t)$(hour(t) >= 7 and hour(t) < 18) = 10;

Resources