Reputation: 649
I have a number of plots which I'm trying to plot as a smooth curve instead of a line plot with markers that are volatile, is there any option to do this? Below is an example dictionary which represents one of the plots, I'm then converting that dict into a DataFrame and throwing it in to plotly. The thing is, the plot doesn't look clean (it fluctuates a lot), I want something that smoothes it out, is there an option to do that?
uncert = {0.01: 0.3132940811899597,
0.03: 0.3654332700822265,
0.05: 0.26783984501130126,
0.07: 0.4321293089229754,
0.09: 0.25012641159615706,
0.11: 0.3714236470182696,
0.13: 0.38346262341325815,
0.15: 0.35005413208228076,
0.17: 0.5588615782664942,
0.19: 0.5836015906078394,
0.21: 0.5266019417475728,
0.23: 0.6645418326693228,
0.25: 0.6699386503067485,
0.27: 0.6684177348182391,
0.29: 0.711600777705768,
0.31: 0.7152067585593596,
0.33: 0.6994047619047619,
0.35: 0.6908919301557338,
0.37: 0.7428780131482835,
0.39: 0.6894644204174001,
0.41: 0.7527301092043682,
0.43: 0.816200215285253,
0.45: 0.8000557724484105,
0.47: 0.7623733719247467,
0.49: 0.843609022556391,
0.5: 0.7963190184049078,
0.52: 0.8063279002876317,
0.54: 0.8296098699566522,
0.56: 0.8319386331938632,
0.58: 0.7823228634039445,
0.6: 0.7898773006134969,
0.62: 0.8312474767864352,
0.64: 0.8414997869620793,
0.66: 0.8583032490974728,
0.68: 0.8475551294343241,
0.7: 0.8271983640081799,
0.72: 0.8509589041095891,
0.74: 0.848377581120944}
plot = pd.DataFrame({"uncert":uncert})
fig = px.line(plot, x='% data', y=plot.columns[1:], markers=True, title="")
Upvotes: 1
Views: 3691
Reputation: 31146
from scipy import signal
import pandas as pd
import plotly.express as px
import statsmodels.api as sm
uncert = {
0.01: 0.3132940811899597,
0.03: 0.3654332700822265,
0.05: 0.26783984501130126,
0.07: 0.4321293089229754,
0.09: 0.25012641159615706,
0.11: 0.3714236470182696,
0.13: 0.38346262341325815,
0.15: 0.35005413208228076,
0.17: 0.5588615782664942,
0.19: 0.5836015906078394,
0.21: 0.5266019417475728,
0.23: 0.6645418326693228,
0.25: 0.6699386503067485,
0.27: 0.6684177348182391,
0.29: 0.711600777705768,
0.31: 0.7152067585593596,
0.33: 0.6994047619047619,
0.35: 0.6908919301557338,
0.37: 0.7428780131482835,
0.39: 0.6894644204174001,
0.41: 0.7527301092043682,
0.43: 0.816200215285253,
0.45: 0.8000557724484105,
0.47: 0.7623733719247467,
0.49: 0.843609022556391,
0.5: 0.7963190184049078,
0.52: 0.8063279002876317,
0.54: 0.8296098699566522,
0.56: 0.8319386331938632,
0.58: 0.7823228634039445,
0.6: 0.7898773006134969,
0.62: 0.8312474767864352,
0.64: 0.8414997869620793,
0.66: 0.8583032490974728,
0.68: 0.8475551294343241,
0.7: 0.8271983640081799,
0.72: 0.8509589041095891,
0.74: 0.848377581120944,
}
plot = pd.DataFrame({"uncert": uncert})
fig = (
px.line(plot, y="uncert", markers=True, title="")
.update_traces(name="original")
.add_traces(
px.line(
plot,
y=signal.savgol_filter(
plot["uncert"], 11, 3
), # window size used for filtering
markers=True,
)
.update_traces(name="savgol")
.data
)
.add_traces(
px.line(
plot,
y=sm.nonparametric.lowess(plot["uncert"], plot.index, frac=0.3)[
:, 1
], # window size used for filtering
markers=True,
)
.update_traces(name="lowres")
.data
)
.update_traces(showlegend=True, line_color=None)
)
fig
Upvotes: 2