I need to add a vertical line to the excel chart similar to below image. The chart is developed using Xlsxwriter==1.2.9.
I am trying to pass a single value (passing a single cell range) to the values field and removed the categories tab.
chart.add_series({'name': 'Vertical Line',
'values':f"{sheet_name,2,5,2,5}",
'line': {'width': 2.5, 'dash_type': 'dash', 'color': '#9ED8D2'}})
Please advice.
Picture reference:
https://www.officetooltips.com/excel_2016/tips/how_to_add_a_vertical_line_to_the_chart.html
The following code will duplicate the example from 'how_to_add_a_vertical_line_to_the_chart.html' fairly close.
When the date is changed in cell 'D4' the vertical line will move to the corresponding date on the x-axis.
import xlsxwriter
workbook = xlsxwriter.Workbook('xlsxwriter_vline_chart.xlsx')
worksheet = workbook.add_worksheet()
### Add the worksheet data to be plotted.
### Set column widths
worksheet.set_column(1, 3, 12)
### Common format
common_format = workbook.add_format({
'border': 1,
})
### Add Headers
Header_data = ['', 'Day', 'New Sales']
cformat = workbook.add_format({
'bold': True,
'bg_color': '#92D050',
'border': 1,
})
worksheet.write_row('B5', Header_data, cformat)
### ID Column
id_data = list(range(1,16))
worksheet.write_column('B6', id_data, common_format)
### Day Column
dates_format = workbook.add_format({
'num_format': 'd-mmm-yy',
'border': 1,
})
dates_data = list(range(44774, 44789))
worksheet.write_column('C6', dates_data, dates_format)
### Values Column
values_data = [132, 128, 95, 115, 83, 87, 67, 97, 112, 84, 77, 97, 86, 77, 83]
worksheet.write_column('D6', values_data, common_format)
### Add Date for Vertical line position
vh_format = workbook.add_format({
'bold': True,
'border': 1,
})
worksheet.write('C4', 'Vert line Date', vh_format)
vd_format = workbook.add_format({
'bold': True,
'num_format': 'd-mmm-yy',
'font_color': 'red'
})
worksheet.write('D4', 44780, vd_format)
### Create a new chart object [Line Chart].
chart_name = 'Chart Test'
chart = workbook.add_chart({'type': 'line'})
chart.add_series({
'name': 'Data',
'values': '=Sheet1!$D$6:$D$20',
'categories': '=Sheet1!$C$6:$C$20',
'smooth': True,
})
### Add 2nd series for the Vertical Line [Scatter Chart]
scatter_series = workbook.add_chart({'type': 'scatter'})
### Set vertical line chart data and format
scatter_series.add_series({
'name': 'VerticalLine',
'categories': '=Sheet1!$D$4',
'values': '=Sheet1!$D$6:$D$20',
'marker': {'type': 'none'},
'line': {'color': 'red',
'width': 1.5,
},
'y_error_bars': {
'type': 'fixed',
'value': 80,
'direction': 'minus',
'line': {'color': 'red',
'width': 1.5,
'dash_type': 'dash',
}
},
})
# # Combine both Line and Scatter charts
chart.combine(scatter_series)
### Chart customisation
chart.set_title({'name': 'Line Chart with Dynamic Vertical line'})
chart.set_size({'width': 580})
chart.set_x_axis({
'name': 'Day',
'date_axis': True,
'minor_unit': 1,
'minor_unit_type': 'days',
'major_unit': 2,
'major_unit_type': 'days',
})
chart.set_y_axis({
'name': 'New Sales',
'min': 60,
'max': 140,
})
# Insert the chart into the worksheet.
worksheet.insert_chart('F6', chart, {'x_scale': 2, 'y_scale': 1})
workbook.close()
Related
I am trying to create a spreadsheet plot with a line and two scatter charts. I am trying to have different symbols for each scatter chart:
# create the chart and add it to the workbook:
value_line_chart = workbook.add_chart({'type': 'line'})
value_line_chart.set_y_axis({'name': 'Values'})
value_line_chart.set_x_axis({'name': 'Time'})
value_line_chart.set_title({'name': 'Chart of {}'.format(historical_data.symbol)})
value_line_chart.add_series({
'line': {
'color': 'cyan',
'width': .5
},
'values': [worksheet.name, data_start_row, value_col, last_col, value_col],
'categories': [worksheet.name, data_start_row, date_col, last_col, date_col],
'name': "data",
})
scatter_buy_chart = workbook.add_chart({'type': 'scatter'})
scatter_buy_chart.add_series({
'marker': {
'type': 'long_dash',
'size': 5,
'border': {'color': 'red'},
'fill': {'color': 'red'},
},
'values': [worksheet.name, data_start_row, buy_action_col, last_col, buy_action_col],
'categories': [worksheet.name, data_start_row, date_col, last_col, date_col],
'name': "buy",
})
value_line_chart.combine(scatter_buy_chart)
scatter_sell_chart = workbook.add_chart({'type': 'scatter'})
scatter_sell_chart.add_series({
'marker': {
'type': 'plus',
'size': 5,
'border': {'color': 'green'},
'fill': {'color': 'green'},
},
'values': [worksheet.name, data_start_row, sell_action_col, last_col, sell_action_col],
'categories': [worksheet.name, data_start_row, date_col, last_col, date_col],
'name': "buy",
})
value_line_chart.combine(scatter_sell_chart)
value_line_chart.set_size({'width': 720, 'height': 576})
value_line_chart.set_x_axis({
'date_axis': True,
'min': date_data[0],
'max': date_data[len(date_data)-1]
})
value_line_chart.set_legend({'none': True})
worksheet.insert_chart('B1', value_line_chart)
workbook.close()
The problems that I am having are:
I am unable to get the second scatter chart to show up
I am unable to get the colors of the symbols to change
I have tried rendering the line and scatter charts individually and the the data and symbol shapes show up correctly.
I am able to change the color of the line chart.
I am able to change the shape of the symbols.
I am able to render the line chart and only one of the two scatter charts.
I was able to get the results I was looking for by adding all of the series into the single chart:
# create the chart and add it to the workbook:
chart = workbook.add_chart({'type': 'line'})
chart.set_y_axis({'name': 'Values'})
chart.set_x_axis({'name': 'Time'})
chart.set_title({'name': 'Chart of {}'.format(historical_data.symbol)})
chart.add_series({
'line': {
'color': 'cyan',
'width': .5
},
'values': [worksheet.name, data_start_row, value_col, last_col, value_col],
'categories': [worksheet.name, data_start_row, date_col, last_col, date_col],
'name': "data",
})
chart.add_series({
'marker': {
'type': 'long_dash',
'size': 8,
'border': {'color': 'red'},
'fill': {'color': 'red'},
},
'values': [worksheet.name, data_start_row, buy_action_col, last_col, buy_action_col],
'categories': [worksheet.name, data_start_row, date_col, last_col, date_col],
'name': "buy",
})
chart.add_series({
'marker': {
'type': 'plus',
'size': 8,
'border': {'color': 'green'},
'fill': {'color': 'green'},
},
'values': [worksheet.name, data_start_row, sell_action_col, last_col, sell_action_col],
'categories': [worksheet.name, data_start_row, date_col, last_col, date_col],
'name': "buy",
})
chart.set_size({'width': 720, 'height': 576})
chart.set_x_axis({
'date_axis': True,
'min': date_data[0],
'max': date_data[len(date_data)-1]
})
chart.set_legend({'none': True})
worksheet.insert_chart('B1', chart)
workbook.close()
It isn’t possible to combine more than 2 charts with XlsxWriter. That is a limitation of the library.
I have some data I'm putting on a Plotly gauge. Not sure how I managed to get a rounded number but I'd like the complete and acurate value to displayed in the text instead of just 1k, for instance my data should now say $1,001.50 but it instead says 1k.
Not too worried about the "ticks" using the k, just the text.
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Indicator(
domain = {'row': 1, 'column': 0},
value = 1001.50,
mode = "gauge+number",
title = {'text': "Total Donations"},
delta = {'reference': 46000},
gauge = {'axis': {'range': [None, 46000]},
'threshold' : {
'line': {'color': "red", 'width': 4},
'thickness': 0.75,
'value': 40000
}}))
fig.add_trace(go.Indicator(
mode = "number+delta",
value = 540,
number = {'prefix': "$"},
delta = {'position': "top", 'reference': 450},
domain = {'row': 1, 'column': 1}))
fig.update_layout(
grid = {'rows': 1, 'columns': 2, 'pattern': "independent"},
template = {'data' : {'indicator': [{
'title': {'text': "Donations this Month"},
'mode' : "number+delta+gauge",
'delta' : {'reference': 90}}]
}})
Select General for the number formatting. See here.
fig.add_trace(go.Indicator(
domain = {'row': 1, 'column': 0},
value = 1001.50,
mode = "gauge+number",
number = {'valueformat':"g"},
title = {'text': "Total Donations"},
delta = {'reference': 46000},
gauge = {'axis': {'range': [None, 46000]},
'threshold' : {'line': {'color': "red", 'width': 4}, 'thickness': 0.75, 'value': 40000}}))
have a pie chart defined here:
chart_1 = workbook.add_chart({'type': 'pie'})
chart_1.add_series({
'name': 'Pie data',
'categories': '=Sheet2!$A$1:$A$' + str(len(cat_count)),
'values': '=Sheet2!$B$1:$B$' + str(len(cat_count)),
'data_labels': {'value': True, 'leader_lines': True, 'name': 'georgia',
'font': {'size': 25, 'color': 'white', 'bold': True}},
})
I am trying to add some formatting , particularly a 'gerogia' font to the categories so they are uniform with the rest of my file
You almost had the syntax correct apart from needing to set the name as part of the font sub-properties.
Here is a small working example:
import xlsxwriter
workbook = xlsxwriter.Workbook('chart_pie.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write_column('A2', ['Apple', 'Cherry', 'Pecan'])
worksheet.write_column('B2', [30, 30, 30])
chart = workbook.add_chart({'type': 'pie'})
chart.add_series({
'name': 'Pie data',
'categories': ['Sheet1', 1, 0, 3, 0],
'values': ['Sheet1', 1, 1, 3, 1],
'data_labels': {'value': True,
'leader_lines': True,
'font': {'size': 25,
'name': 'georgia',
'color': 'white',
'bold': True}},
})
chart.set_legend({'font': {'name': 'georgia'}})
worksheet.insert_chart('C2', chart, {'x_offset': 25, 'y_offset': 10})
workbook.close()
Output:
Note also the somewhat easier programatic way of setting the range for the categories and values.
I am going through the the slider animation plot tutorial from plotly (https://plot.ly/python/animations/), the one at the bottom, with my own data. My scenario is basically is data gathered from users from an application. I have data for one month (May), which the frequency of users are recorded hourly for each day. I want to use a slider to have a range of values from day 1 to 31 and the plot to show the unique values of each hour for each specific day.
My problem: I only get day one, but the value of the slider is updating correctly. Fixed old problem, now I have another one: Now instead of 1 step of the data, the graph is showing every single step.
My code:
# dMay to DataFrame
dfMay = pd.DataFrame({key :dMay[key] for key in list(dMay.keys())})
for i, df in enumerate([dfMay], 1):
df.columns = [str(col_name)[6:].format(i) for col_name in df.columns]
keys = list(map(lambda x: str(x), dfMay.keys())) # Slider values - days
from plotly.grid_objs import Grid, Column
listOfCols = []
for col in keys:
listOfCols.append(Column(dfMay[col], col))
grid = Grid(listOfCols)
py.grid_ops.upload(grid, 'Testing'+str(time.time()), auto_open=False)
# Animated Plot
figure = {
'data': [],
'layout': {},
'frames': []
}
# fill in most of layout
figure['layout']['xaxis'] = {'range': [0, 23], 'title': 'Zaman (saat)'}
figure['layout']['yaxis'] = {'title': 'Kullanıcı Sayısı', 'type': 'linear'}
figure['layout']['hovermode'] = 'closest'
figure['layout']['sliders'] = {
'args': [
'transition', {
'duration': 400,
'easing': 'cubic-in-out'
}
],
'initialValue': '0',
'plotlycommand': 'animate',
'values': list(range(24)),
'visible': True
}
figure['layout']['updatemenus'] = [
{
'buttons': [
{
'args': [None, {'frame': {'duration': 500, 'redraw': True},
'fromcurrent': True, 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
'label': 'Play',
'method': 'animate'
},
{
'args': [[None], {'frame': {'duration': 0, 'redraw': True}, 'mode': 'immediate',
'transition': {'duration': 0}}],
'label': 'Pause',
'method': 'animate'
}
],
'direction': 'left',
'pad': {'r': 10, 't': 87},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}
]
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Zaman:',
'visible': True,
'xanchor': 'right'
},
'transition': {'duration': 300, 'easing': 'cubic-in-out'},
'pad': {'b': 10, 't': 50},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}
# make data
start = 0
for day in keys:
data_dict = {
'x': list(range(24)),
'y': list(dfMay[day]),
'mode': 'markers',
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': 20
},
'name': day
}
figure['data'].append(data_dict)
# make frames
for day in keys:
frame = {'data': [], 'name': str(day)}
data_dict = {
'x': list(range(24)),
'y': list(dfMay[day]),
'mode': 'markers',
'text': list(dfMay[day]),
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': 20
},
'name': day,
}
frame['data'].append(data_dict)
figure['frames'].append(frame)
slider_step = {'args': [
[day],
{'frame': {'duration': 1000, 'redraw': True},
'mode': 'immediate',
'transition': {'duration': 1000}}
],
'label': day,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
print('Done')
plot(figure)
I also can,t get rid of the colored markers on the right!
EDIT 1: Added dfMay Table
EDIT 2: Changed problem, added a new plot
Images to Supplement:
Fixes slider related issue. I followed another plotly tutorial. https://plot.ly/~empet/14896
plotData=[dict(type='scatter',
x=list(range(24)),
y=test_data[:0],
mode='markers',
marker=dict(size=10, color='red')
)
]
frames=[dict(data=[dict(y=test_data[:,k])],
traces=[0],
name=f'{k+1}',
layout=dict(yaxis=dict(range=[-1, test_data[:, k].max()+100]))) for k in range(31)]
sliders=[dict(steps= [dict(method= 'animate',
args= [[ f'{k+1}'],
dict(mode= 'e',
frame= dict( duration=1000, redraw= False ),
transition=dict( duration= 0)
)
],
label=f' {k+1}'
) for k in range(31)],
transition= dict(duration= 30 ),
x=0,#slider starting position
y=0,
currentvalue=dict(font=dict(size=12),
prefix='Day: ',
visible=True,
xanchor= 'center'
),
len=1.0,
active=1) #slider length)
]
axis_style=dict(showline=True,
mirror=True,
zeroline=False,
ticklen=4)
layout=dict(title='Mayıs-Günlük Kullanıcı Sayıları',
width=900,
height=600,
autosize=False,
xaxis=dict(axis_style, dtick=1, tit='s' title='Zaman (saat)', **dict(range=[0,24])),
yaxis=dict(axis_style, title='Kullanıcı Sayısı',autorange=False),
#plot_bgcolor="rgba(66,134,244, 0.2)",
shapes= [dict(
# Sabah
type= 'rect',
xref= 'x',
yref= 'paper',
x0= '0',
y0= 0,
x1= '8',
y1= 1,
fillcolor= 'rgba(66, 134, 244, 0.5)',
opacity= 0.2,
line= dict(width= 0)
),
# Oglen
dict(
type= 'rect',
xref= 'x',
yref= 'paper',
x0= '8',
y0= 0,
x1= '16',
y1= 1,
fillcolor= '#rgba(255, 252, 117,1)',
opacity= 0.2,
line= dict(width=0)
),
# Aksam
dict(
type= 'rect',
xref= 'x',
yref= 'paper',
x0= '16',
y0= 0,
x1= '24',
y1= 1,
fillcolor= 'rgba(2, 0, 168, 1)',
opacity= 0.2,
line= dict(width=0)
)
],
hovermode='closest',
updatemenus=[dict(type='buttons', showactive=True,
y=0,
x=1.15,
xanchor='right',
yanchor='top',
pad=dict(t=0, r=10),
buttons=[dict(label='Play',
method='animate',
args=[None,
dict(frame=dict(duration=4000,
redraw=True),
transition=dict(duration=4000),
fromcurrent=True,
mode='immediadate'
)
]
),
dict(label='Pause',
method='animate',
args=[[None],
dict(frame=dict(duration=0,
redraw=False),
transition=dict(duration=30),
fromcurrent=True,
mode='immediate'
)
]
)
]
)
],
sliders=sliders
)
# Animated Plot
figure = {
'data': plotData,
'layout': layout,
'frames': frames
}
fig=dict(data=plotData, frames=frames, layout=layout)
fig['data'][0].update(mode='markers+lines',
line=dict(width=1.5, color='blue'))
plot(fig, auto_open=False)
I have this chart, created using python package xlsxwriter and I wanna remove all the points in the middle and only keep the first one and last one.
before :
Final results wanted.:
I tried the attribute points but unfortunate, it didn't work for me.
line_chart.add_series(
{
'values': '='+worksheet_name+'!$C$'+str(row_range+1)+':$I'+str(row_range+1),
'marker': {'type': 'diamond'},
'data_labels': {'value': True, 'category': True, 'position': 'center', 'leader_lines': True},
'points': [
{'fill': {'color': 'green'}},
None,
None,
None,
None,
None,
{'fill': {'color': 'red'}}
],
'trendline': {
'type': 'polynomial',
'name': 'My trend name',
'order': 2,
'forward': 0.5,
'backward': 0.5,
'line': {
'color': 'red',
'width': 1,
'dash_type': 'long_dash'
}
}
}
)
I also tried:
line_chart.set_x_axis({
'major_gridlines': {'visible': False},
'minor_gridlines': {'visible': False}
'delete_series': [1, 6]
})
no luck.
Anobody can help me please?
Thanks in advance!