Published on
November 24, 2021
Updated on
May 8, 2023
‣
Evolution of approval rates
Approval rate is in green, disapproval rate in orange. Each point represent a poll, and lines are centered 30-day moving averages.
super-embed:
<iframe src="https://storage.googleapis.com/charlse/charlse/macron_popularity.html" height="520"><iframe>
‣
# Plotly graph
## Colors
color_approval = {
'Approve': 'darkgreen',
'approval': 'darkgreen',
'Disapprove': 'darkorange',
'disapproval': 'darkorange',
'Neutral': 'grey',
}
## Line graph for rolling means
fig1 = px.line(
df_popularity, x='date', y=['Approve', 'Disapprove'],
color_discrete_map=color_approval)
fig1.update_traces(hovertemplate='%{y:.1%}', showlegend=True, line=dict(width=3))
fig1.add_hline(y=.5)
## Scatter graph
fig2 = px.scatter(
df_popularity, x='date', y=['approval', 'disapproval'],
opacity=.3, color_discrete_map=color_approval)
fig2.update_traces(hovertemplate=None, hoverinfo='skip', showlegend=False)
## Group both plots
fig3 = go.Figure(
data=fig1.data + fig2.data,
layout=go.Layout(
template='simple_white',
height=500, width=740,
margin=dict(l=5, r=5, b=5,t=5),
yaxis_tickformat='.0%', yaxis_range=[0, 1],
yaxis_tickfont=dict(size=11, family='Arial'),
xaxis_tickfont=dict(size=11, family='Arial'),
showlegend=False,
hovermode='x unified',
)
)
## Display result
fig3.show()
‣
Polling institute | Poll date | Sample size | Approval rate | Disapproval rate |
Harris Interactive | 2023-04-25 | 1078 | 39% | 61% |
Odoxa | 2023-04-19 | 1005 | 30% | 70% |
BVA | 2023-04-18 | 1002 | 26% | 73% |
Ifop | 2023-04-14 | 1955 | 26% | 72% |
Ipsos | 2023-04-12 | 1000 | 28% | 69% |
Harris Interactive | 2023-03-28 | 1062 | 39% | 61% |
BVA | 2023-03-24 | 1000 | 28% | 72% |
Odoxa | 2023-03-22 | 1004 | 30% | 70% |
Ifop | 2023-03-09 | 1928 | 28% | 70% |
Ipsos | 2023-02-24 | 1014 | 32% | 64% |
BVA | 2023-02-22 | 1001 | 34% | 66% |
Odoxa | 2023-02-21 | 1005 | 36% | 63% |
Harris Interactive | 2023-02-21 | 1008 | 42% | 58% |
Ifop | 2023-02-09 | 1952 | 32% | 66% |
Ifop-Fiducial | 2023-02-01 | 1012 | 34% | 66% |
Compared to Previous French Presidents
Comparaison of Emmanuel Macron popularity vs previous French presidents, monthly since their election or re-election. Note: since 2002 (Chirac II), the duration of a presidential mandate decreased from 7 years to 5 years.
super-embed:
<iframe src="https://storage.googleapis.com/charlse/charlse/presidents.html" height="820"><iframe>
‣
# Plot Macron vs previous presidents
## Selection
presidents = [
'Mitterrand I', 'Mitterrand II',
'Chirac I', 'Chirac II',
'Sarkozy', 'Hollande'
]
## Plot
fig = make_subplots(
rows=(len(presidents)+1)//2, cols=2,
vertical_spacing = 0.1,
subplot_titles=["{}".format(i) for i in presidents]
)
fig.update_annotations(font_size=14, font_family='Arial')
## Loop over candidates couples
for i,v in enumerate(presidents):
### Macron 1st or 2nd mandate
if v[-2:] == 'II':
macron = 'Macron II'
else:
macron = 'Macron I'
### Previous president
fig.add_trace(go.Scatter(
x=df_presidents.loc[lambda x: x['president'] == v, 'months'],
y=df_presidents.loc[lambda x: x['president'] == v, 'trust']/100,
line=dict(shape='hv', width=1, color='dimgray'),
mode='lines',
hovertemplate='<extra>{}</extra>%{}'.format(v, '{y:.0%}')
),
row=i//2+1, col=i%2+1)
### Trick for fill area
fig.add_trace(go.Scatter(
x=df_presidents.loc[lambda x: x['president'] == macron, 'months'],
y=df_presidents.loc[lambda x: x['president'] == v, 'trust']/100,
line=dict(shape='hv', color='dimgray', width=0),
mode='lines',
hoverinfo='skip'
),
row=i//2+1, col=i%2+1)
### Macron score
fig.add_trace(go.Scatter(
x=df_presidents.loc[lambda x: x['president'] == macron, 'months'],
y=df_presidents.loc[lambda x: x['president'] == macron, 'trust']/100,
line=dict(shape='hv', width=2, color='steelblue'),
mode='lines',
hovertemplate='<extra>{}</extra>%{}'.format(macron, '{y:.0%}'),
fill='tonexty', fillcolor='rgba(70,130,180,0.2)'
),
row=i//2+1, col=i%2+1)
### Axes formatting
fig.update_yaxes(tickformat='.0%', range=[0, 1],
tickfont=dict(size=11, family='Arial'))
fig.update_xaxes(
tickmode = 'array',
tickvals=[12, 24, 36, 48, 60, 72, 84],
ticktext = ['1 year', '2 years', '3 years', '4 years', '5 years', '6 years', '7 years'],
tickfont=dict(size=11, family='Arial'),
ticksuffix=' months',
)
## Figure formatting
fig.update_layout(
template='simple_white',
width=740, height=800,
showlegend=False,
margin=dict(l=15, r=25, b=15,t=40),
hovermode='x unified',
)
## Display results
fig.show()
Sources
- FiveThirtyEight for inspiration
- List of polls for Emmanual Macron popularity
- Kantar barometer for presidents popularity index