Skip to content

Instantly share code, notes, and snippets.

@miguel9554
Last active December 17, 2025 02:07
Show Gist options
  • Select an option

  • Save miguel9554/4afdde0e8030e47db3aae795c822977e to your computer and use it in GitHub Desktop.

Select an option

Save miguel9554/4afdde0e8030e47db3aae795c822977e to your computer and use it in GitHub Desktop.
Plot de carga fiscal del monotributo
import pandas as pd
import plotly.graph_objects as go
import numpy as np
df = pd.DataFrame({
"Categoria": list("ABCDEFGHIJK"),
"Ingreso_anual": [
8992597.87, 13175201.52, 18473166.15, 22934610.05,
26977793.60, 33809379.57, 40431835.35, 61344853.64,
68664410.05, 78632948.76, 94805682.90,
],
"Total_mensual": [
37085.74, 42216.41, 49435.58, 63357.80, 89714.31,
112906.59, 172457.38, 391400.62, 721650.46,
874069.29, 1208890.60,
],
})
df["Ingreso_mensual"] = df["Ingreso_anual"] / 12
df["Total_anual"] = df["Total_mensual"] * 12
df["Porcentaje_ingreso"] = df["Total_anual"] / df["Ingreso_anual"] * 100
# Convertir a millones
df["Ingreso_anual_mill"] = df["Ingreso_anual"] / 1e6
df["Ingreso_mensual_mill"] = df["Ingreso_mensual"] / 1e6
# Redondear a 3 cifras significativas SOLO para el eje X anual
df["Ingreso_anual_mill_round"] = df["Ingreso_anual_mill"].apply(lambda x: round(x, 3 - len(str(int(x)))))
# Calcular mensual como anual_redondeado / 12
df["Ingreso_mensual_mill_round"] = df["Ingreso_anual_mill_round"] / 12
# Crear datos para escalones (gasto constante por categoría)
x_escalon = []
y_escalon = []
for i in range(len(df)):
if i == 0:
x_escalon.extend([0, df["Ingreso_anual_mill_round"].iloc[i]])
else:
x_escalon.extend([df["Ingreso_anual_mill_round"].iloc[i-1], df["Ingreso_anual_mill_round"].iloc[i]])
y_escalon.extend([df["Total_mensual"].iloc[i], df["Total_mensual"].iloc[i]])
# Crear datos interpolados para porcentaje (varía continuamente)
# Solo a partir de 4 millones
x_continuo = []
y_porcentaje = []
min_ingreso_mill = 4.0 # Mínimo en millones
for i in range(len(df)):
if i == 0:
inicio = df["Ingreso_anual"].iloc[i] * 0.001
else:
inicio = df["Ingreso_anual"].iloc[i-1]
fin = df["Ingreso_anual"].iloc[i]
# Generar puntos intermedios
n_puntos = 50
for j in range(n_puntos):
ingreso = inicio + (fin - inicio) * j / (n_puntos - 1)
ingreso_mill = ingreso / 1e6
# Solo agregar si es >= 4 millones
if ingreso_mill >= min_ingreso_mill:
x_continuo.append(ingreso_mill)
porcentaje = (df["Total_mensual"].iloc[i] * 12) / ingreso * 100
y_porcentaje.append(porcentaje)
# 👇 Hardcodeado: 1,500,000 ARS = 20%
max_ars = 1500000
max_porcentaje = 20
fig = go.Figure()
# Escalones para gasto mensual (constante por categoría)
fig.add_trace(go.Scatter(
x=x_escalon,
y=y_escalon,
mode="lines",
name="Gasto mensual [ARS]",
line=dict(shape='hv'),
yaxis="y1",
xaxis="x",
))
# Puntos y etiquetas en los límites de categoría (ABAJO del punto)
fig.add_trace(go.Scatter(
x=df["Ingreso_anual_mill_round"],
y=df["Total_mensual"],
mode="markers+text",
text=df["Categoria"],
textposition="bottom center",
marker=dict(size=8),
showlegend=False,
yaxis="y1",
xaxis="x",
))
# Línea continua para porcentaje - AHORA EN Y2 con valores originales
fig.add_trace(go.Scatter(
x=x_continuo,
y=y_porcentaje, # 👈 Valores originales de porcentaje
mode="lines",
name="Gasto mensual [%]",
yaxis="y2", # 👈 Ahora va en y2
xaxis="x",
))
# Traza invisible para forzar xaxis2
fig.add_trace(go.Scatter(
x=df["Ingreso_anual_mill_round"],
y=[None] * len(df),
xaxis="x2",
yaxis="y",
showlegend=False,
hoverinfo="skip",
))
fig.update_layout(
title=f"Carga fiscal del monotributo con categorías del 1/08/2025",
xaxis=dict(
title="Ingreso bruto anual [millones de ARS]",
tickvals=df["Ingreso_anual_mill_round"],
ticktext=[f"{v:.3g}" for v in df["Ingreso_anual_mill_round"]],
side="bottom",
),
xaxis2=dict(
title="Ingreso bruto mensual [millones de ARS]",
overlaying="x",
side="top",
tickvals=df["Ingreso_anual_mill_round"],
ticktext=[f"{v:.3g}" for v in df["Ingreso_mensual_mill_round"]],
showgrid=False,
),
yaxis=dict(
title="Gasto mensual [ARS]",
tickformat="$,.0f",
),
yaxis2=dict(
title="Gasto mensual [%]",
overlaying="y",
side="right",
tickformat=".2f",
),
legend=dict(
x=0.01,
y=0.99,
xanchor="left",
yanchor="top",
bgcolor="rgba(255,255,255,0.8)",
),
hovermode="x unified",
)
fig.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment