Add custom markers to Gantt Chart in Plotly - python-3.x

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

Related

Plotly does not color-code my chart according to the variable indicated

I have the problem that when I concatenate two csv and create a column "Version" with string values, plotly does NOT generate the classification of each of the values, in this case 1 and 2. However, when this variable is numeric, it does generate a continuous classification (I need a discrete classification).
Image shows concatenation and data type
Two legends are observed, but only one color is observed
This is an example of how it doesn't work. However, if I change the variable to continuous, it does work.
I am generating this block to generate graphs for each type of group. Which should be my final result.
grouped = df_final.groupby('Name')
plots = []
for name, group in grouped:
# create a new figure for the group
fig = px.scatter(group.reset_index(), x="Time", y="Observed", opacity=1, width=800, height=600,
color = "Version)
fig.show()
This block generates the chart with its legend, but does not show the colors in the chart.
I am starting with python and plotly, any help would be appreciated.
I'm trying to understand why plotly doesn't sort my string variables

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?

How to add text on interactive Scatter on Altair?

I try to adapt the Selection Detail Example from altair doc (https://altair-viz.github.io/gallery/select_detail.html#selection-detail-example).
I won't detailed my Dataframe structure which is identical with the one from the example (included variable names).
The native code is working well :
# Data is prepared, now make a chart
selector = alt.selection_single(empty='all', fields=['id'])
base = alt.Chart(data).properties(
width=250,
height=250
).add_selection(selector)
points = base.mark_point(filled=True, size=200,opacity=0.9).encode(
x=alt.X('mean(y)',title='Durée de perception',scale=alt.Scale(domain=(11, 23))),
y=alt.Y('mean(x)',title='Taux de marge (%PM)'),
color=alt.condition(selector, 'id:O', alt.value('lightgray')),
tooltip = ['mean(y)','mean(x)']
)
timeseries = base.mark_bar(opacity=1).encode(
x=alt.X('time', title='Items'),
y=alt.Y('value', scale=alt.Scale(domain=(-1, 1)),stack=None),
color=alt.Color('id:O',scale=alt.Scale(domain=domain, range=range_))
#, legend=None)
).transform_filter(
selector
)
points | timeseries
No problem at this stage even if it could be useful to hide all the bars on right chart when no selection is made on the right chart (don't know if it's possible ?)
After that I try to add text to the scatter plot adding this at the end of the code :
text = points.mark_text(dy=-5).encode(
x=alt.X('mean(y)',title='Durée de perception',scale=alt.Scale(domain=(11, 23))),
y=alt.Y('mean(x)',title='NBV (%CA)'),
text='id:O'
)
(points + text) | timeseries
which leads to the following error message :
Javascript Error: Duplicate signal name: "selector094_tuple"
This usually means there's a typo in your chart specification. See the javascript console for the full traceback.
If you have any idea on how to do, i would be grateful
Thanks
The issue is that you cannot add the same selection to two different layers, which you do implicitly by deriving text from points. Try this instead:
text = alt.Chart(data).mark_text(dy=-5).encode(
x=alt.X('mean(y)',title='Durée de perception',scale=alt.Scale(domain=(11, 23))),
y=alt.Y('mean(x)',title='NBV (%CA)'),
text='id:O'
)
(points + text) | timeseries

Having both X and Y axes' Scales in Altair respond to a selection interval

I'm bringing this question from Altair's github. (https://github.com/altair-viz/altair/issues/2456) Is there a way to get the Scale on Y-axis in the bottom chart to respond to the selection brush? I'd like to be able to pan around the top chart with a selection and see the zoomed-in results in the bottom chart. If I uncomment the alt.Y, then both the X and Y axes show Years and it's messed up. Is there a way to pass just an X or Y value in the 'brush' maybe? Thank you very much!
brush = alt.selection_interval(init={'x':[1950, 1970], 'y':[1500000, 2500000]}, encodings=['x', 'y'])
base = alt.Chart().mark_line().encode(
x=alt.X('Year:Q', title=None),
y='Deaths:Q',
color='Entity:N'
)
alt.vconcat(
base.add_selection(brush).encode().properties(height=150, width=150),
base.encode(
alt.X('Year:Q', scale=alt.Scale(domain=brush)),
#alt.Y('Deaths:Q', scale=alt.Scale(domain=brush)) # (un)commenting this line makes it work/fail only along the x-axis
).properties(
height=500, width=500
),
data='https://vega.github.io/vega-datasets/data/disasters.csv'
)
Yes, see Open the Chart in the Vega Editor
It filters the data of the 2nd chart using a filter transform on the brush param.

Plot points playing games when I try to size by a value count in bokeh

I'm trying to get the plot points in a scatter graph to size according to the frequency of values in a column of data. The data is coming from a questionnaire.
My questions are: What am I doing wrong, and what can I do to fix it?
I can push out a simple plot with x and y values coming from 2 columns of data. The X axis represents a level (1-100), and the Y axis represents a choice users can make for each level (1-4). For this plot I want to track how many people choose 1-4 on each level - so I need to capture that 1-4 has been selected, then indicate how many times.
Simple plot works fine, though those points have multiple occurrences.
Here's the code for that:
# Set up the graph
WT_Number = data.wt # This is the X axis
CFG_Number = data.cfg # This is the Y axis
wt_cfg_plot = figure(plot_width=1000, plot_height=400,
title="Control Form Groups chosen by WT unit")
# Set up the plot points, including the Hover Tool
cr = wt_cfg_plot.scatter(WT_Number, CFG_Number, size=7,
fill_color="blue",
line_color=None, alpha=0.7, hover_fill_color="firebrick",
hover_line_color=None, hover_alpha=1)
Problem: I then added a value count and set it as the size, to get the plot points to adjust according to the value frequency. But now it pumps out this chart and throws an error:
Plot points are reacting to the code, but now they're doing their own thing.
I added a variable for the value counts (cfg_freq), and used that as the size:
cfg_freq = data['cfg'].value_counts()*4
cr = wt_cfg_plot.scatter(WT_Number, CFG_Number, size=cfg_freq, fill_color="blue",
line_color=None, alpha=0.7, hover_fill_color="firebrick",
hover_line_color=None, hover_alpha=1)
Here's the the last part of the error being thrown:
File "/Applications/anaconda/lib/python3.5/site-packages/bokeh/core/properties.py", line 722, in setattr
(name, self.class.name, text, nice_join(matches)))
AttributeError: unexpected attribute 'size' to Chart, possible attributes are above, background_fill_alpha, background_fill_color, below, border_fill_alpha, border_fill_color, disabled, extra_x_ranges, extra_y_ranges, h_symmetry, height, hidpi, left, legend, lod_factor, lod_interval, lod_threshold, lod_timeout, logo, min_border, min_border_bottom, min_border_left, min_border_right, min_border_top, name, outline_line_alpha, outline_line_cap, outline_line_color, outline_line_dash, outline_line_dash_offset, outline_line_join, outline_line_width, plot_height, plot_width, renderers, responsive, right, tags, title, title_standoff, title_text_align, title_text_alpha, title_text_baseline, title_text_color, title_text_font, title_text_font_size, title_text_font_style, tool_events, toolbar_location, tools, v_symmetry, webgl, width, x_mapper_type, x_range, xgrid, xlabel, xscale, y_mapper_type, y_range, ygrid, ylabel or yscale

Resources