Hello,
J'ai developpé il y a quelques temps une CGI en ksh/html qui permettait de créer des graph via Gnuplot à partir de data récoltées sur des serveurs Linux et AIX. Les datas sont de ce type :
2020-01-13-00-00,384.00,350.00
2020-01-13-06-00,384.00,350.00
2020-01-13-12-00,384.00,350.00
2020-01-13-18-00,384.00,350.00
2020-01-14-00-00,384.00,350.00
2020-01-14-06-00,384.00,350.00
2020-01-14-12-00,384.00,350.00
Aujourd'hui j'aimerai pouvoir faire évoluer cette CGI en la passant sous python et en utilisant les libraires pandas, ipywidget et plotly.express.
J'ai fait un premier script qui ressemble à cela :
import pandas as pd
import plotly.express as px
df = pd.read_csv('Bureau/Test.txt')
df.head()
fig = px.line(df, x = 'Date', y ='Total Used', title='DF command graph')
fig.add_scatter(x=df['Date'], y=df['Free'])
fig.update_traces(mode='markers+lines')
fig.write_html("/xxx/xxx/xxx/file.html")
fig.show()
Ce script me permettait d'exporter au format html mon graph tout en gardant le côté " interactif ".
Mon objectif maintenant est de faire la même chose mais en ajoutant un bouton qui afficherait le graph et un autre bouton qui afficherait le graph avec la courbe de tendance. De ce fait, j'ai ce script :
import ipywidgets as widgets
import pandas as pd
import plotly.express as px
import os
####### Button 1 ########
button = widgets.Button(description="graph")
display(button)
def graph():
df = pd.read_csv('/xxx/xxx/xxx/Test.txt')
df.head()
fig = px.line(df, x = 'Date', y ='Total Used', title='DF command graph')
fig.update_traces(mode='markers')
fig.show();
output = widgets.Output()
@output.capture()
def on_button_clicked(b):
graph();
button.on_click(on_button_clicked)
display(output)
####### Button 2 #########
button2 = widgets.Button(description='trend')
display(button2)
def trend():
df = pd.read_csv('/xxx/xxx/xxx/Test.txt')
df.head()
fig = px.scatter((df), x="Date", y="Total Used", trendline="ols")
fig.show()
output2 = widgets.Output()
@output2.capture()
def on_button2_clicked(b):
trend()
button2.on_click(on_button2_clicked)
display(output2)
graph()
Le bouton pour afficher le graph fonctionne super bien. Mais lorsque j'essaie d'utiliser le bouton trend, voici l'erreur qui s'affiche :
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~/.local/lib/python3.7/site-packages/ipywidgets/widgets/widget_output.py in inner(*args, **kwargs)
101 self.clear_output(*clear_args, **clear_kwargs)
102 with self:
--> 103 return func(*args, **kwargs)
104 return inner
105 return capture_decorator
<ipython-input-14-bc7c0aeca03e> in on_button2_clicked(b)
40 @output2.capture()
41 def on_button2_clicked(b):
---> 42 trend()
43
44 button2.on_click(on_button2_clicked)
<ipython-input-14-bc7c0aeca03e> in trend()
33 df = pd.read_csv('/home/tim/Bureau/Test1.txt')
34 df.head()
---> 35 fig = px.scatter(df, x="Date", y="Total Used", trendline="ols")
36 fig.show()
37
~/.local/lib/python3.7/site-packages/plotly/express/_chart_types.py in scatter(data_frame, x, y, color, symbol, size, hover_name, hover_data, custom_data, text, facet_row, facet_col, facet_col_wrap, error_x, error_x_minus, error_y, error_y_minus, animation_frame, animation_group, category_orders, labels, color_discrete_sequence, color_discrete_map, color_continuous_scale, range_color, color_continuous_midpoint, symbol_sequence, symbol_map, opacity, size_max, marginal_x, marginal_y, trendline, trendline_color_override, log_x, log_y, range_x, range_y, render_mode, title, template, width, height)
53 mark in 2D space.
54 """
---> 55 return make_figure(args=locals(), constructor=go.Scatter)
56
57
~/.local/lib/python3.7/site-packages/plotly/express/_core.py in make_figure(args, constructor, trace_patch, layout_patch)
1315
1316 patch, fit_results = make_trace_kwargs(
-> 1317 args, trace_spec, group, mapping_labels.copy(), sizeref
1318 )
1319 trace.update(patch)
~/.local/lib/python3.7/site-packages/plotly/express/_core.py in make_trace_kwargs(args, trace_spec, g, mapping_labels, sizeref)
234 hover_header = "<b>LOWESS trendline</b><br><br>"
235 elif v == "ols":
--> 236 fit_results = sm.OLS(y.values, sm.add_constant(x.values)).fit()
237 result["y"] = fit_results.predict()
238 hover_header = "<b>OLS trendline</b><br>"
~/.local/lib/python3.7/site-packages/statsmodels/tools/tools.py in add_constant(data, prepend, has_constant)
303 raise ValueError('Only implementd 2-dimensional arrays')
304
--> 305 is_nonzero_const = np.ptp(x, axis=0) == 0
306 is_nonzero_const &= np.all(x != 0.0, axis=0)
307 if is_nonzero_const.any():
<__array_function__ internals> in ptp(*args, **kwargs)
~/.local/lib/python3.7/site-packages/numpy/core/fromnumeric.py in ptp(a, axis, out, keepdims)
2541 else:
2542 return ptp(axis=axis, out=out, **kwargs)
-> 2543 return _methods._ptp(a, axis=axis, out=out, **kwargs)
2544
2545
~/.local/lib/python3.7/site-packages/numpy/core/_methods.py in _ptp(a, axis, out, keepdims)
230 umr_maximum(a, axis, None, out, keepdims),
231 umr_minimum(a, axis, None, None, keepdims),
--> 232 out
233 )
234
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Je ne comprends pas la signification de cette erreur… Serait-ce parce que dans mes datas, le script ne comprendrait pas 2020-01-13-00-00
, prenant le signe - comme un signe de soustraction ? Pourriez-vous me montrer comment corriger ça ?
Ensuite, deuxième problème, dans mon premier script j'ai réussi à créer un .html grâces a la ligne :
fig.write_html("/xxx/xxx/xxx/file.html")
Avec mon nouveau script, n'y a t-il pas un moyen de faire la même chose ? Sans passer par jupyer notebook ou quoi ?
# Mauvais type
Posté par Eh_Dis_Mwan . Évalué à 0.
Ton code essaie de faire une soustraction entre deux string. Force le passage en int
[^] # Re: Mauvais type
Posté par fab . Évalué à 1.
Si je comprends bien,
OK :
fig.add_scatter(x=df['Date'], y=df['Free'])
Pas OK :
fig = px.scatter((df), x="Date", y="Total Used", trendline="ols")
L'erreur est peu parlante car elle est levée à assez bas niveau, lors de l'évaluation de la trendline.
Est-ce que df['Date'] est bien reconnu comme de type Date (cf https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html par ex) et non comme simple String ? C'est un prérequis pour faire de l'arithmétique sur ces données…
Pandas est en général assez intelligent sur la détection & interprétation des données, mais il faut un peu l'aider : l'argument dtype de read_csv devrait t'être utile.
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html?highlight=read_csv#pandas-read-csv
Par ailleurs, je devine que tu as pondu deux instructions différentes pour la même fonctionnalité parce que tu n'as pas encore d'objet fig dans le second cas. De manière générale, dans une GUI avec affichage de graphes, tu peux préférer créer d'abord les structures type figure, axes, labels, légende, etc… pour ensuite les modifier/réutiliser en fonction des nouvelles données.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.