remove points from excel file line chart using python package xlsxwriter - python

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!

Related

Can plotly(python) slider start static (without animation) in html file?

I have been trying to create a plotly figure (scatter plot) with a date slider and then exporting the figure to an HTML file.
To do so I have used the plotly px library: px.scatter(animation_frame...), just as in the second example here: https://plotly.com/python/sliders/.
Once I have the figure I save it to a HTML file with fig.to_html(full_html=False, include_plotlyjs='cdn').
This does work, but the problem I face is that the slider starts animating the frames by default whenever I open the html file. Is there a way to make the slider start static by default? I need it to start static because the figure has many frames and the slider automatically updating the frames makes the file really slow.
My code is:
figDVTO = px.scatter(dfPrueba, x="DíasVencimiento", y="Inflación", labels=dict(DíasVencimiento="Días al Vencimiento", Inflación="Inflación Implícita (%)"),
animation_frame="Fecha", title="Curva Inflación Implícita Diaria", range_y=[1, 8],
range_x=[0,7000], color = "Implícita", color_discrete_map = dicColores)
figDVTO.update_traces(marker=dict(size=12, line=dict(width=2,
color='DarkSlateGrey')),
selector=dict(mode='markers'))
I tried to set the "stop" animation button as default, but even when I do so, the slider animates the frames.
I also tried to construct the figure with plotly.graph_objects Figure, by constructing the dictionary that contains the frames.
I am able to recreate the figure I create with plotly express. However, after looking in plotly´s documentation I´m still no sure how to make the slider initially static. Have tried changing the method in updatemenus, as well as changing the method in sliders, but nothing seems to work.
I would really appreciate any sort of help, been scratching my head for weeks now...
Here is my complete code to construct the figure with plotly.graph_objects:
# make figure
fig_dict = {
"data": [],
"frames": [],
"layout": {'legend': {'title': {'text': 'Implícita'}, 'tracegroupgap': 0},
'sliders': [{
'active': 0,
'currentvalue': {'prefix': 'Fecha='},
'len': 0.9,
'pad': {'b': 10, 't': 60},
'steps':[],
'x': 0.1,
'xanchor': 'left',
'y': 0,
'yanchor': 'top'
}],
'title': {'text': 'Curva Inflación Implícita Diaria',
'font':dict(
family="Arial",
size=18,
)
},
'updatemenus': [{'active': 0,
'bgcolor': '#B0BEC5',
'buttons': [{'args': [None, {'frame': {'duration':
500, 'redraw': False},
'mode': 'immediate',
'fromcurrent': True,
'transition': {'duration':
500, 'easing': 'linear'}}],
'label': '▶',
'method': 'animate'},
{'args': [[None], {'frame':
{'duration': 0, 'redraw':
False}, 'mode': 'immediate',
'fromcurrent': True,
'transition': {'duration': 0,
'easing': 'linear'}}],
'label': '◼',
'method': 'animate'}],
'direction': 'left',
'pad': {'r': 10, 't': 70},
'showactive': True,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'}],
'xaxis': {'anchor': 'y',
'domain': [0.0, 1.0],
'range': [0, 7000],
'title': {'text': 'Días al Vencimiento'}},
'yaxis': {'anchor': 'x',
'domain': [0.0, 1.0],
'range': [1, 8],
'title': {'text': 'Inflación Implícita (%)'}}
}
}
#Creating starting frame
listFechas = list(dfPrueba['Fecha'].unique())
listImplicitas = list(dfPrueba['Implícita'].unique())
fecha=listFechas[0]
for implicita in listImplicitas:
data_dict = {
"x": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'DíasVencimiento']),
"y": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'Inflación']),
'legendgroup': str(implicita),
'hovertemplate': ('Implícita='+ str(implicita)+'<br>Fecha='+str(fecha)+'<br>Días al Vencimiento=%{x}<br>Inflación Implícita (%)=%{y}<extra></extra>'),
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"mode": "markers",
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"name": str(implicita),
'orientation': 'v',
'showlegend': True,
'type': 'scatter',
'xaxis': 'x',
'yaxis': 'y',
}
fig_dict["data"].append(data_dict)
# make frames
for fecha in listFechas:
frame = {"data": [], "name": str(fecha)}
for implicita in listImplicitas:
data_dict = {
"x": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'DíasVencimiento']),
"y": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'Inflación']),
'legendgroup': str(implicita),
'hovertemplate': ('Implícita='+ str(implicita)+'<br>Fecha='+str(fecha)+'<br>Días al Vencimiento=%{x}<br>Inflación Implícita (%)=%{y}<extra></extra>'),
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"mode": "markers",
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"name": str(implicita),
'orientation': 'v',
'legendgroup': '23',
'showlegend': True,
'type': 'scatter',
'xaxis': 'x',
'yaxis': 'y'
}
frame["data"].append(data_dict)
fig_dict["frames"].append(frame)
#Updating sliders steps
for fecha in listFechas:
loop_dic={'args': [[str(fecha)], {'frame':
{'duration': 0, 'redraw': False},
'mode': 'immediate', 'fromcurrent':
True, 'transition': {'duration': 0,
'easing': 'linear'}}],
'label': str(fecha),
'method': 'animate'}
fig_dict["layout"]["sliders"][0]["steps"].append(loop_dic)
#Creating figure
figB = go.Figure(fig_dict)
figB.update_layout(
title="Curva Inflación Implícita Diaria",
xaxis_title="Días al Vencimiento",
yaxis_title="Inflación Implícita (%)",
legend_title="Serie",
font=dict(
family="Arial",
size=18,
),
hovermode="x",
yaxis=dict(tickformat=".2f")
)

Unable to combine line and two scatter plots in xlsxwriter. Also having problems coloring plot symbols

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.

Attach format to a pie chart xlsxwriter Python

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.

Creating Pandas DataFrame from SmartSheet API (nested, awkward, JSON)

I'm trying to connect to my office's SmartSheet API via Python to create some performance tracking dashboards that utilize data outside of SmartSheet. All I want to do is create a simple DataFrame where fields reflect columnId and cell values reflect the displayValue key in the Smartsheet dictionary. I am doing this using a standard API requests.get rather than SmartSheet's API documentation because I've found the latter less easy to work with.
The table (sample) is set up as:
Number Letter Name
1 A Joe
2 B Jim
3 C Jon
The JSON syntax from the sheet GET request is:
{'id': 339338304219012,
'name': 'Sample Smartsheet',
'version': 1,
'totalRowCount': 3,
'accessLevel': 'OWNER',
'effectiveAttachmentOptions': ['GOOGLE_DRIVE',
'EVERNOTE',
'DROPBOX',
'ONEDRIVE',
'LINK',
'FILE',
'BOX_COM',
'EGNYTE'],
'ganttEnabled': False,
'dependenciesEnabled': False,
'resourceManagementEnabled': False,
'cellImageUploadEnabled': True,
'userSettings': {'criticalPathEnabled': False, 'displaySummaryTasks': True},
'userPermissions': {'summaryPermissions': 'ADMIN'},
'hasSummaryFields': False,
'permalink': 'https://app.smartsheet.com/sheets/5vxMCJQhMV7VFFPMVfJgg2hX79rj3fXgVGG8fp61',
'createdAt': '2020-02-13T16:32:02Z',
'modifiedAt': '2020-02-14T13:15:18Z',
'isMultiPicklistEnabled': True,
'columns': [{'id': 6273865019090820,
'version': 0,
'index': 0,
'title': 'Number',
'type': 'TEXT_NUMBER',
'primary': True,
'validation': False,
'width': 150},
{'id': 4022065205405572,
'version': 0,
'index': 1,
'title': 'Letter',
'type': 'TEXT_NUMBER',
'validation': False,
'width': 150},
{'id': 8525664832776068,
'version': 0,
'index': 2,
'title': 'Name',
'type': 'TEXT_NUMBER',
'validation': False,
'width': 150}],
'rows': [{'id': 8660990817003396,
'rowNumber': 1,
'expanded': True,
'createdAt': '2020-02-14T13:15:18Z',
'modifiedAt': '2020-02-14T13:15:18Z',
'cells': [{'columnId': 6273865019090820, 'value': 1.0, 'displayValue': '1'},
{'columnId': 4022065205405572, 'value': 'A', 'displayValue': 'A'},
{'columnId': 8525664832776068, 'value': 'Joe', 'displayValue': 'Joe'}]},
{'id': 498216492394372,
'rowNumber': 2,
'siblingId': 8660990817003396,
'expanded': True,
'createdAt': '2020-02-14T13:15:18Z',
'modifiedAt': '2020-02-14T13:15:18Z',
'cells': [{'columnId': 6273865019090820, 'value': 2.0, 'displayValue': '2'},
{'columnId': 4022065205405572, 'value': 'B', 'displayValue': 'B'},
{'columnId': 8525664832776068, 'value': 'Jim', 'displayValue': 'Jim'}]},
{'id': 5001816119764868,
'rowNumber': 3,
'siblingId': 498216492394372,
'expanded': True,
'createdAt': '2020-02-14T13:15:18Z',
'modifiedAt': '2020-02-14T13:15:18Z',
'cells': [{'columnId': 6273865019090820, 'value': 3.0, 'displayValue': '3'},
{'columnId': 4022065205405572, 'value': 'C', 'displayValue': 'C'},
{'columnId': 8525664832776068, 'value': 'Jon', 'displayValue': 'Jon'}]}]}
Here are the two ways I've approached the problem:
INPUT:
from pandas.io.json import json_normalize
samplej = sample.json()
s_rows = json_normalize(data=samplej['rows'], record_path='cells', meta=['id', 'rowNumber'])
s_rows
OUTPUT:
DataFrame with columnId, value, disdlayValue, id, and rowNumber as their own fields.
If I could figure out how to transpose this data in the right way I could probably make it work, but that seems incredibly complicated.
INPUT:
samplej = sample.json()
cellist = []
def get_cells():
srows = samplej['rows']
for s_cells in srows:
scells = s_cells['cells']
cellist.append(scells)
get_cells()
celldf = pd.DataFrame(cellist)
celldf
OUTPUT:
This returns a DataFrame with the correct number of columns and rows, but each cell is populated with a dictionary that looks like
In [14]:
celldf.loc[1,1]
Out [14]:
{'columnId': 4022065205405572, 'value': 'B', 'displayValue': 'B'}
If there was a way to remove everything except the value corresponding to the displayValue key in every cell, this would probably solve my problem. Again, though, it seems weirdly complicated.
I'm fairly new to Python and working with API's, so there may be a simple way to address the problem I'm overlooking. Or, if you have a suggestion for approaching the possible solutions I outlined above I'm all ears. Thanks for your help!
You must make use of the columns field:
colnames = {x['id']: x['title'] for x in samplej['columns']}
columns = [x['title'] for x in samplej['columns']]
cellist = [{colnames[scells['columnId']]: scells['displayValue']
for scells in s_cells['cells']} for s_cells in samplej['rows']]
celldf = pd.DataFrame(cellist, columns=columns)
This gives as expected:
Number Letter Name
0 1 A Joe
1 2 B Jim
2 3 C Jon
If some cells could contain only a columnId but no displayValue field, scells['displayValue'] should be replaced in above code with scells.get('displayValue', defaultValue), where defaultValue could be None, np.nan or any other relevant default.

Numpy 3D array slice viewer in Plotly

Displaying one slice of a numpy 3D array in Plotly is easy, just use a Heatmap:
import plotly.offline as offline
import plotly.graph_objs as go
import numpy as np
trace = go.Heatmap(z=3D_array[10,:,:]) # just one slice (10) along x axis
fig = dict(data=[trace])
offline.plot(fig, filename='heatmap.html')
What I want is to have a slider to see any slice. Using a few examples over the web I came up with this:
figure = {
'data': [],
'layout': {},
'frames': [],
}
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Year:',
'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': []
}
frame = {'data': []}
for i in range(A.shape[0]):
frame['data'].append(A[i, :, :])
figure['frames'].append(frame)
slider_step = {'args': [
[i],
{'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}}
],
'label': i,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
figure['data'] = [go.Heatmap(z=A[10,:,:])]
print(figure.keys())
offline.plot(figure, filename='heatmap.html')
I can't get it to work. I feel like there is a problem with passing data for consecutive frames.
Any tips on how to proceed?

Categories

Resources