I'm trying to add an interactive shape (circle) to a set of subplots (for simplicity, below I use only one empty plot to create a simple reproducible example).
Intended behaviour of the code below is to be able to switch between two different circles using a drop down menu.
import plotly.plotly as py
import plotly.graph_objs as go
from plotly import tools
# Create empty plot to put shapes into
scatter = go.Scatter()
fig = tools.make_subplots(cols=1)
fig.append_trace(scatter, 1, 1)
# Create two different shapes to select from
fig['layout']['shapes'].append(
{
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1,
'visible':True
})
fig['layout']['shapes'].append(
{
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 0.5, 'y1': 0.5,
'visible':False
})
# This doesn't work
fig['layout']['updatemenus'] =
[{
x:-0.05, y:0.8,
buttons=[
{args:['layout.shapes.visible', [True, False]], label:'1', method:'restyle'},
{args:['layout.shapes.visible', [False, True]], label:'2', method:'restyle'}
]
}]
py.plot(fig, filename='shape_select')
I assume my mistake is that I refer to visible parameter in a wrong way, and layout.shapes.visible should be replaced with something else.
So, how do I properly refer to shape parameters in this case?
Either I am too stupid to find the obvious solution, but this seems like a like a bug or unspecified behavior to me.
The last 8 drop down items reliably work. The first 8 have some unspecified behavior depending on the order they are clicked and might interfere one with another..
The suggested solution uses argument unpacking to create the dictionaries for the shapes on the fly and setting visible for each shape.
import plotly
shape1 = {
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1,
'line': {'color': 'rgb(0, 0, 255)'}
}
shape2 = {
'type': 'circle',
'xref': 'x', 'yref': 'y',
'x0': 0, 'y0': 0, 'x1': 0.5, 'y1': 0.5,
'line': {'color': 'rgb(255, 0, 255)'}
}
trace0 = plotly.graph_objs.Scatter(
x= [0.2, 0.2, 0.3, 0.4, 0.2],
y= [0.2, 0.5, 0.8, 0.3, 0.2]
)
data = plotly.graph_objs.Data([trace0])
layout = plotly.graph_objs.Layout(shapes=[shape1, shape2])
fig = plotly.graph_objs.Figure(data=data, layout=layout)
fig['layout']['shapes'].append(dict(visible=True, **shape1))
fig['layout']['shapes'].append(dict(visible=True, **shape2))
fig['layout']['updatemenus'] = [dict(
x=-0.05, y=0.8,
buttons=[
dict(args=['shapes.visible', [False, True]], label='Hide big - does not work', method='relayout'),
dict(args=['shapes.visible', [True, False]], label='Hide small - does not work', method='relayout'),
dict(args=['shapes[0].visible', False], label='Hide big - might work', method='relayout'),
dict(args=['shapes[1].visible', False], label='Hide small - might work', method='relayout'),
dict(args=['shapes[0].visible', True], label='Show big', method='relayout'),
dict(args=['shapes[1].visible', True], label='Show small', method='relayout'),
dict(args=['shapes', [dict(visible=True, **shape1), dict(visible=True, **shape2)]], label='Show all', method='relayout'),
dict(args=['shapes', [dict(visible=False, **shape1), dict(visible=False, **shape2)]], label='Hide all', method='relayout'),
dict(args=['shapes', [dict(visible=True, **shape1), dict(visible=False, **shape2)]], label='Show big, hide small', method='relayout'),
dict(args=['shapes', [dict(visible=False, **shape1), dict(visible=True, **shape2)]], label='Hide big, show small', method='relayout')
]
)]
plotly.offline.plot(fig, filename='shape_select.html')
This a bit more compact solution works as well:
fig['layout']['updatemenus'] = [dict(
x=-0.05, y=0.8,
dict(args=[{'shapes[0].visible': True, 'shapes[1].visible': False}], label='First circle', method='relayout'),
dict(args=[{'shapes[0].visible': False, 'shapes[1].visible': True}], label='First circle', method='relayout'),
]
)]
Related
I'm somewhere between beginner and intermediate level using Dart/Flutter combination.
I'm building a Marine logbook whereby I need to be able to log a duty that is made up a a variable number of activities. See the code below. In this example I have two duties that each comprise 1 activity.
List<Map<String, dynamic>> duties = [
{
'date': '12122021',
'dutyStart': '00:00',
'dutyFinish': '12:00',
'skipper': 'Mark',
'crew': 'My Crew',
'assets': 'G1',
'activity': [
{
'activityType': 'Training',
'trainingActivityDetail': 'Navigation',
'wapolJobNumber': null,
'rapNumber': null,
'activityStart': '02:00',
'activityFinish': '03:00',
'startFuel': 100,
'endFuel': 300,
'fuelUsed': 200,
}
],
},
{
'date': '01092021',
'dutyStart': '18:00',
'dutyFinish': '23:00',
'skipper': 'Neil',
'crew': 'My Crew',
'assets': 'G2',
'activity': [
{
'activityType': 'WAMSAR',
'trainingActivityDetail': null,
'wapolJobNumber': '123',
'rapNumber': '456',
'activityStart': '19:00',
'activityFinish': '20:00',
'startFuel': 1000,
'endFuel': 3000,
'fuelUsed': 2000,
}
],
}
];
I've worked out how to add a duty with the following code:
//add a duty
duties.add(
{
'date': '111111',
'dutyStart': '11:11',
'dutyFinish': '22:22',
'skipper': 'Tom',
'crew': 'My Crew',
'assets': 'Ranger',
'activity': [
{
'activityType': 'WAMSAR',
'trainingActivityDetail': null,
'wapolJobNumber': '000',
'rapNumber': '999',
'activityStart': '19:00',
'activityFinish': '20:00',
'startFuel': 1000,
'endFuel': 3000,
'fuelUsed': 2000,
}
],
},
);
But I can't work out how to add an activity to a duty.
For example, how would I add the activity below to the last duty so that the last duty now has 2 activities instead of 1?:
{
'activityType': 'XXX',
'trainingActivityDetail': null,
'wapolJobNumber': '000',
'rapNumber': '999',
'activityStart': '19:00',
'activityFinish': '20:00',
'startFuel': 1000,
'endFuel': 3000,
'fuelUsed': 2000,
}
For now I'm just using the data in a listview builder that isn't being saved anywhere. It will end up being saved in firestore cloud. Just wondering as well how I might save an activity in firestore? I'm happy with saving a duty in firestore but haven't taken the leap into saving lists in lists yet.
Apologies if this has been covered previously. I did check prior to posting but didn't see anything of help.
you can try this. Here we insert the activity element in the last duty as follows:
duties.last["activity"].add(
{
'activityType': 'WAMSAR',
'trainingActivityDetail': null,
'wapolJobNumber': '000',
'rapNumber': '999',
'activityStart': '19:00',
'activityFinish': '20:00',
'startFuel': 1000,
'endFuel': 3000,
'fuelUsed': 200023,
}
);
print(duties);
Output
[{date: 12122021, dutyStart: 00:00, dutyFinish: 12:00, skipper: Mark, crew: My Crew, assets: G1, activity: [{activityType: Training, trainingActivityDetail: Navigation, wapolJobNumber: null, rapNumber: null, activityStart: 02:00, activityFinish: 03:00, startFuel: 100, endFuel: 300, fuelUsed: 200}]}, {date: 01092021, dutyStart: 18:00, dutyFinish: 23:00, skipper: Neil, crew: My Crew, assets: G2, activity: [{activityType: WAMSAR, trainingActivityDetail: null, wapolJobNumber: 123, rapNumber: 456, activityStart: 19:00, activityFinish: 20:00, startFuel: 1000, endFuel: 3000, fuelUsed: 2000}, {activityType: WAMSAR, trainingActivityDetail: null, wapolJobNumber: 000, rapNumber: 999, activityStart: 19:00, activityFinish: 20:00, startFuel: 1000, endFuel: 3000, fuelUsed: 200023}]}]
I have created Highcharts graph by this code:
def chart_data(request):
dataset = DispatchPlan.objects.annotate(month=TruncMonth('scheduled_date')).values('month').annotate(
c=Sum('weight')).values('month', 'c')
chart = {
'chart': {'type': 'column'},
'title': {'text': 'Weight Dispatched by Months'},
'series': [{
'name': 'Months',
'data': [{'name': row['month'], 'y': row["c"]} for row in dataset]
}]
}
return JsonResponse(chart)
How can I add the X axis labels such that it shows month name instead of 0 and 1 ?
This is the one row of dataset from which the graph is plotted
{'month': datetime.datetime(2019, 6, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>), 'c': 17600}
Try to use strftime (documentation) like that :
{'month': datetime.datetime(2019, 6, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>).strftime("%B"), 'c': 17600}
I running a script to take rows and columns from a worksheet and use it to make charts. The problem that I am running into is that since the rows in the MSEXCEL sheet are changing, I want to add the last row in the add_series argument so that it will always take the limit of the chart data from row 2 till the last row.
This is the code that I am using currently (that I want to change):
chart1 = workbook.add_chart({'type': 'column'})
chart1.add_series({
'values': "='Sheet1'!$B$2:$B$126",
'categories': "='Sheet1'!$A$2:$A$126",
'data_labels': {'value': False, 'categories': False, 'series': False}
})
I have modified the above code to the following, but now the charts are not getting any data whatsoever.
chart1 = workbook.add_chart({'type': 'column'})
chart1.add_series({
'values': "='Sheet1'!$B$2:($B$ + str(last_row_number + 1)",
'categories': "='Sheet1'!$A$2:($A$ + str(last_row_number + 1)",
'data_labels': {'value': False, 'categories': True, 'series': False}
last_row_number in this case is a variable [<type 'int'>] calculated by enumerating through the worksheet column.
Thanks in advance.
Almost every interface in XlsxWriter supports (row, col) notation as well as A1 range notation.
In the case of add_series() you can use lists like [sheetname, first_row, first_col, last_row, last_col]:
chart.add_series({
'categories': ['Sheet1', 1, 0, 125, 0],
'values': ['Sheet1', 1, 1, 125, 1],
# ...
})
# Or:
last_row = 125
chart.add_series({
'categories': ['Sheet1', 1, 0, last_row, 0],
'values': ['Sheet1', 1, 1, last_row, 1],
# ...
})
See the docs for add_series().
I have the following code from edited from: How to plot pie charts as subplots with custom size with Plotly in Python
import plotly
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=True)
labels = ['Oxygen','Hydrogen','Carbon_Dioxide','Nitrogen']
values = [4500,2500,1053,500]
domains = [
{'x': [0.0, 0.33], 'y': [0.0, 0.50]},
{'x': [0.33, 0.66], 'y': [0.0, 0.50]},
{'x': [0.66, 1], 'y': [0.0, 0.50]},
{'x': [0.0, 0.33], 'y': [0.50, 1]},
{'x': [0.33, 0.66], 'y': [0.50, 1]},
{'x': [0.66, 1], 'y': [0.50, 1]},
]
traces = []
valueslist = []
for domain in domains:
trace = go.Pie(labels = labels,
values = values,
domain = domain)
traces.append(trace)
layout = go.Layout(height = 600,
width = 600,
autosize = False,
title = 'Main title')
fig = go.Figure(data = traces, layout = layout)
py.iplot(fig, show_link = False, image='png')
I am trying to plot 6 pie charts at one time with different values and different titles for each chart. How should I add these extra lists? Assume, I have the following lists to add:
values1 = [5, 6, 1, 2]
values2 = [1, 4, 5, 6]
values3 = [2, 6, 2, 4]
values4 = [1, 5, 3, 7]
values5 = [25, 51, 33, 47]
#with following titles:
title = 'title0'
title1 = 'title1'
title2 = 'title2'
title3 = 'title3'
title4 = 'title4'
title5 = 'title5'
I've got the template to render manually, but not the dates with a filter. Is there a way of doing this without formatting the dates before I put them in the context?
Here is the code:
t= This is to notify you that you are booked on the course {{title}} that starts on {{start_date|date:"F j, Y"}} at {{start|time}} and is being held at {{venue}}.
c = {'startdate': datetime.datetime(2010, 12, 1, 9, 0), 'enddate': datetime.datetime(2010, 12, 1, 12, 0), 'has_cpd': False, 'title': 'Course 1', 'closes': None, 'creator': 1L, 'venue': 'Venue for Course 1', 'summary': 'Course 1 Summary', 'tags': '', 'attachment': <FieldFile: None>, 'organiser': 3L, 'id': 1L, 'opens': datetime.datetime(2010, 11, 30, 20, 1, 50, 951490), 'venue_map': None}
t.render(c)
This gives the output:
This is to notify you that you are booked on the course Course 1 that starts on at and is being held at Venue for Course 1.
Why don't the dates show up?
Looks like a simple typo between start_date vs. startdate.
In [18]: t= Template("""This is to notify you that you are booked on the course {{title}} that starts on {{startdate|date:"F j, Y"}} at {{start|time}} and is being held at {{venue}}.""")
In [19]: t.render(c)Out[19]: u'This is to notify you that you are booked on the course Course 1 that starts on December 1, 2010 at and is being held at Venue for Course 1.'