cyberosa
commited on
Commit
·
3f72b8c
1
Parent(s):
12536a4
Improving the divergence graph
Browse files- app.py +5 -1
- notebooks/closed_markets.ipynb +56 -0
- notebooks/divergence.ipynb +0 -0
- tabs/market_plots.py +56 -17
app.py
CHANGED
@@ -20,7 +20,11 @@ from tabs.trader_plots import (
|
|
20 |
get_interpretation_text,
|
21 |
)
|
22 |
|
23 |
-
from tabs.market_plots import
|
|
|
|
|
|
|
|
|
24 |
|
25 |
|
26 |
def get_logger():
|
|
|
20 |
get_interpretation_text,
|
21 |
)
|
22 |
|
23 |
+
from tabs.market_plots import (
|
24 |
+
plot_kl_div_per_market,
|
25 |
+
plot_kl_div_with_off_by,
|
26 |
+
plot_kl_div_per_market2,
|
27 |
+
)
|
28 |
|
29 |
|
30 |
def get_logger():
|
notebooks/closed_markets.ipynb
CHANGED
@@ -1954,6 +1954,62 @@
|
|
1954 |
"source": [
|
1955 |
"np.log(1/0.01)"
|
1956 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1957 |
}
|
1958 |
],
|
1959 |
"metadata": {
|
|
|
1954 |
"source": [
|
1955 |
"np.log(1/0.01)"
|
1956 |
]
|
1957 |
+
},
|
1958 |
+
{
|
1959 |
+
"cell_type": "code",
|
1960 |
+
"execution_count": 11,
|
1961 |
+
"metadata": {},
|
1962 |
+
"outputs": [
|
1963 |
+
{
|
1964 |
+
"data": {
|
1965 |
+
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAJOCAYAAACqS2TfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB7lUlEQVR4nO3deVwV9f7H8fcBBFwQNAQEFVRcckFNk2vuSaKVpdlNvd1c8uqvrno1stLKXSPNyrqaS2WabbZpt80yEs0yLU3NTFMyyQXcAgEVlfP9/UGcPAIKyHAAX8/H4zxkvjPznc8AR32f78x3bMYYIwAAAAAAUOzcXF0AAAAAAADlFaEbAAAAAACLELoBAAAAALAIoRsAAAAAAIsQugEAAAAAsAihGwAAAAAAixC6AQAAAACwCKEbAAAAAACLELoBAAAAALAIoRsALPDbb7/JZrNpyZIlri4FLjJ58mTZbDZXl5GvJUuWyGaz6bfffivwtt9//731hV1g1apVatmypby9vWWz2ZSSkiJJWrZsmRo3bqwKFSrIz88v3/3DwsJ06623lkyxAADkg9ANoEzLLwykpqaqbdu28vb21qpVqyT9FYKOHTtW6OPYbDbHy8PDQ9WrV1fr1q01evRo7dy5s1jOBQUXFhbm9DPx9vZWgwYN9NBDD+nEiROuLu+KvfDCCy75wMbq43799dfq06ePAgMD5eXlpbCwMP3f//2fEhMTc217/Phx3XXXXapYsaLmzZunZcuWqXLlytq1a5cGDx6s+vXr68UXX9SiRYssq7cgcj5gy3m5u7urTp066tOnj7Zu3erS2orDqVOnNHnyZMXHx7u6FAAoszxcXQAAFLeTJ0+qe/fu2r59u1asWKEePXoUS7833XSTBg4cKGOMUlNTtW3bNi1dulQvvPCCZs6cqZiYGMe2oaGhOn36tCpUqFAsx0ZuLVu21IMPPihJOnPmjDZv3qw5c+Zo7dq12rRpk4uruzIvvPCC/P39NXjwYMuOcc8996h///7y8vIqkeP+97//1ejRo1WvXj2NGjVKNWvW1M8//6yXXnpJy5cv1yeffKIbbrjBsf13332ntLQ0TZs2TVFRUY72+Ph42e12PffccwoPDy/2OotqwIABuvnmm5WVlaWff/5Z8+fP16effqpvv/1WLVu2dHV5RXbq1ClNmTJFktSlSxfXFgMAZRShG0C5kpaWpujoaG3dulXvv/++evbsWWx9N2zYUP/85z+d2p588kn16tVLDz74oBo3bqybb75ZkhyjryUtIyNDlStXLvHjukJISIjTz+Nf//qXqlSpotmzZ2vPnj1q0KCBC6sr/dzd3eXu7l4ix/r66681ZswYdejQQatWrVKlSpUc6+6//361b99ed955p3766SdVq1ZNknTkyBFJynX5eH7trnbdddc5/T62b99et912m+bPn6+FCxdeUd9X0/saAMojLi8HUG6kp6erR48e2rJli9577z3dcsstlh/zmmuu0VtvvSUPDw/NmDHD0X7xPd2zZ8+WzWbT/v37c/Uxfvx4eXp66o8//nC0bdy4UT169JCvr68qVaqkzp076+uvv3baL+dy+Z07d+of//iHqlWrpg4dOkiS7Ha7Jk+erODgYFWqVEldu3bVzp07FRYWlmsUMyUlRWPGjFHt2rXl5eWl8PBwzZw5U3a7Pdf5zJ49W4sWLVL9+vXl5eWl66+/Xt99912uc9q1a5fuuusu1ahRQxUrVlSjRo302GOPOW1z8OBB3XvvvY5LjZs2barFixcX7Bufj6CgIEmSh4fzZ8pffvmlOnbsqMqVK8vPz0+33367fv75Z8f6V155RTabLdfxn3jiCdlsNn3yySe5vg/PPvusQkNDVbFiRXXu3Fk7duy4bH3nz5/XtGnTHN+/sLAwPfroo8rMzHRsExYWpp9++klr1651XLJ8qRHG6667TnfccYdTW/PmzWWz2bR9+3ZH2/Lly2Wz2RznffE93QU5bmZmpmJiYlSjRg1VrlxZffr00dGjRy973tOmTZPNZtPSpUudArck1a9fX7NmzdLhw4cd4bRLly4aNGiQJOn666+XzWbT4MGDFRYWpkmTJkmSatSoIZvNpsmTJ1/2+J9//rnj3vAmTZro/fffd6z79ddfZbPZ9Oyzz+ba75tvvpHNZtObb7552WNc7MYbb5Qk7du3z9F2pe9rSXrttdfUtm1bVapUSdWqVVOnTp30+eefO/Xx6aefOn7ffXx8dMstt+inn35y2mbw4MGqUqWKDh48qN69e6tKlSqqUaOGxo4dq6ysLEnZv+81atSQJE2ZMsXxe5HzPd++fbsGDx6sevXqydvbW0FBQbr33nt1/PjxXN+P+Ph4tWnTRt7e3qpfv74WLlyY77wHr732mlq3bq2KFSuqevXq6t+/v37//feCfusBoPQxAFCGvfLKK0aSiY+PNx06dDAVKlQwH3zwQZ7bTpo0yUgyR48eLfRxJJkRI0bku75bt27Gzc3NpKamGmOM2bdvn5FkXnnlFWOMMfv37zc2m83MmjUr17716tUzt9xyi2M5Li7OeHp6mnbt2pmnn37aPPvssyYiIsJ4enqajRs35jqfJk2amNtvv9288MILZt68ecYYYx5++GEjyfTq1cvMnTvXDBs2zNSqVcv4+/ubQYMGOfrIyMgwERER5pprrjGPPvqoWbBggRk4cKCx2Wxm9OjRju1yzqdVq1YmPDzczJw508yaNcv4+/ubWrVqmbNnzzq23bZtm6lataq55pprzPjx483ChQvNww8/bJo3b+7YJikpydSqVcvUrl3bTJ061cyfP9/cdtttRpJ59tlnL/vzCA0NNd27dzdHjx41R48eNb///rv53//+Z4KDg02nTp2ctl29erXx8PAwDRs2NLNmzTJTpkwx/v7+plq1ambfvn2O7W699Vbj6+trEhMTjTHGbN++3Xh6epqhQ4fm+j40b97chIWFmZkzZ5opU6aY6tWrmxo1apikpKRcP58LDRo0yEgyd955p5k3b54ZOHCgkWR69+7t2GbFihWmVq1apnHjxmbZsmVm2bJl5vPPP8/3e/Gf//zH1KhRw7F8/PhxY7PZjJubm5k7d66jfcSIEU7b5bx3cr4HlzpuzratWrUyN954o/nvf/9rHnzwQePu7m7uuuuufGszJvt3zMPDw3Tp0iXfbc6cOWO8vLxM+/btjTHGfP7552b48OFGkpk6dapZtmyZ+eabb8yKFStMnz59jCQzf/58s2zZMrNt27Z8+w0NDTUNGzY0fn5+Zty4ceaZZ54xzZs3N25ubk7f0/bt25vWrVvn2v/f//638fHxMRkZGfkeI+d34qmnnnJq37Ztm5Fk+vfvb4wpnvf15MmTjSRzww03mKeeeso899xz5h//+Id55JFHHPu/+uqrxmazmR49epj//ve/ZubMmSYsLMz4+fk5/b4PGjTIeHt7m6ZNm5p7773XzJ8/3/Tt29dIMi+88IIxxpj09HQzf/58I8n06dPH8XuR8z2fPXu26dixo5k6dapZtGiRGT16tKlYsaJp27atsdvtjmNt2bLFeHl5mbCwMPPkk0+aGTNmmODgYNOiRYtc75Hp06cbm81m+vXrZ1544QXH+zUsLMz88ccf+f4cAKA0I3QDKNNywkBoaKipUKGCWblyZb7bWhm6R48ebSQ5/jN6ceg2xph27drl+o/9pk2bjCTz6quvGmOMsdvtpkGDBiY6OtrpP62nTp0ydevWNTfddFOu8xkwYIBTn0lJScbDw8MpyBnz13/YLwzd06ZNM5UrVza//PKL07bjxo0z7u7ujgCacz7XXHONOXHihGO7Dz74wEgyH374oaOtU6dOxsfHx+zfv9+pzwvPZ+jQoaZmzZrm2LFjTtv079/f+Pr6mlOnTplLCQ0NNZJyvdq3b5+rz5YtW5qAgABz/PhxR9u2bduMm5ubGThwoKPt8OHDpnr16uamm24ymZmZplWrVqZOnTqOD1Iu/D5UrFjRHDhwwNG+ceNGI8k88MADjraLQ/fWrVuNJPOvf/3Lqb6xY8caSebLL790tDVt2tR07tz5kt+DHO+8846RZHbu3GmMMeZ///uf8fLyMrfddpvp16+fY7uIiAjTp08fx/LFoftSx83ZNioqyunn+MADDxh3d3eTkpKSb305533hhzh5iYiIMNWrV891zO+++85pu8K8j3N+T9577z1HW2pqqqlZs6Zp1aqVo23hwoVGkvn5558dbWfPns31IVVecn4npkyZYo4ePWqSkpJMfHy8adWqlePYxfG+3rNnj3FzczN9+vQxWVlZTuty+kxLSzN+fn5m2LBhTuuTkpKMr6+vU3vOB0BTp0512rZVq1ZOf08dPXrUSDKTJk3Kde55vU/ffPNNI8msW7fO0darVy9TqVIlc/DgQafz8fDwcHqP/Pbbb8bd3d3MmDHDqc8ff/zReHh45GoHgLKCy8sBlAvJycny9vZW7dq1XXL8KlWqSMq+pzw//fr10+bNm5WQkOBoW758uby8vHT77bdLkrZu3ao9e/boH//4h44fP65jx47p2LFjysjIULdu3bRu3Tqny74l6b777nNajouL0/nz5/Xvf//bqX3UqFG5anrnnXfUsWNHVatWzXGsY8eOKSoqSllZWVq3bl2uc8i551aSOnbsKCn7El1JOnr0qNatW6d7771XderUcdo35zJSY4zee+899erVS8YYp+NGR0crNTVVW7Zsyff7mCMyMlKrV6/W6tWr9dFHH2nGjBn66aefdNttt+n06dOSpMOHD2vr1q0aPHiwqlev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k09q3Lhx6t+/vx5//HFHQLvQypUrdfDgQcfypk2btHHjxks+Fz7nWHPmzHFqf+aZZyTJ6RF3lStXdqr3cnIuG585c6YiIiLk6+vraI+Li9P3339foEvLC3vcgnr88cdljNHgwYMd99vn2Ldvnx5++GHVrFlT//d//1fovuvVq6eoqCjHq3379k7rDx06pBUrVjiWT548qVdffVUtW7Z0Gg328PDQgAED9Pbbb2vJkiVq3rx5ka+4uFhxvK979+4tNzc3TZ06Ndcocs57Kzo6WlWrVtUTTzyhc+fOFek4F8t5xNvFvxc5H+BcfJXDxb/f7u7uioqK0sqVK3Xo0CFH+969e/Xpp586bXvHHXfI3d1dU6ZMydWvMSbPR5EBQFnASDeAcqdPnz568cUXde+99+q2227TqlWr5O3t7Vj/zDPP5HpWsJubmx599NFL9vvLL7/otddekzFGJ0+e1LZt2/TOO+8oPT1dzzzzjHr06HHZ2gICAtS1a1c988wzSktLU79+/XLV8dJLL6lnz55q2rSphgwZopCQEB08eFBr1qxR1apVHcEyP4GBgRo9erSefvpp3XbbberRo4e2bdumTz/9VP7+/k4jVw899JD+97//6dZbb9XgwYPVunVrZWRk6Mcff9S7776r3377Tf7+/pc9rws9//zz6tChg6677joNHz5cdevW1W+//aaPP/5YW7dulSQ9+eSTWrNmjSIjIzVs2DA1adJEJ06c0JYtW/TFF1/oxIkTlz3OwYMH9dprr0mSzp49q23btmnhwoXy9/d3urT8qaeeUs+ePdWuXTsNHTpUp0+f1n//+1/5+vo6njd85MgR3X///eratatGjhwpKftDijVr1mjw4MFav36902XG4eHh6tChg+6//35lZmZqzpw5uuaaa/K9TF/K/iBg0KBBWrRokVJSUtS5c2dt2rRJS5cuVe/evdW1a1fHtq1bt9b8+fM1ffp0hYeHKyAg4JL3FoeHhysoKEi7d+92OvdOnTrpkUcekaQChe7CHregOnXqpNmzZysmJkYREREaPHiwatasqV27dunFF1+U3W7XJ598kmvOgeLQsGFDDR06VN99950CAwO1ePFiJScn65VXXsm17cCBA/X8889rzZo1Trd9XKnieF+Hh4frscce07Rp09SxY0fdcccd8vLy0nfffafg4GDFxsaqatWqmj9/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ooWio6N15MiRS+7322+/aezYserYsWOe63v06KHDhw87Xm+++aYV5QMAAAAAimDt2rUaMWKEvv32W61evVrnzp1T9+7dlZGRIUk6dOiQDh06pNmzZ2vHjh1asmSJVq1apaFDh16279KUBz1cduQ/PfPMMxo2bJiGDBkiSVqwYIE+/vhjLV68WOPGjctzn6ysLN19992aMmWKvvrqK6WkpOTaxsvLS0FBQVaWDgAAAAAoolWrVjktL1myRAEBAdq8ebM6deqkZs2a6b333nOsr1+/vmbMmKF//vOfOn/+vDw88o+zpSkPunSk++zZs9q8ebOioqIcbW5uboqKitKGDRvy3W/q1KkKCAi45Ccc8fHxCggIUKNGjXT//ffr+PHjxVo7AAAAAKD45Fw2Xr169UtuU7Vq1UsGbql05UGXjnQfO3ZMWVlZCgwMdGoPDAzUrl278txn/fr1evnll7V169Z8++3Ro4fuuOMO1a1bVwkJCXr00UfVs2dPbdiwQe7u7rm2z8zMVGZmpmM5LS2taCcEAABwFXM7neLqEoByryy8z9LS0nTy5EnHspeXl7y8vC65j91u15gxY9S+fXs1a9Ysz22OHTumadOmafjw4Zfsq7B50Gouv7y8MNLS0nTPPffoxRdflL+/f77b9e/f3/F18+bNFRERofr16ys+Pl7dunXLtX1sbKymTJliSc0AAABXi4r71rm6BAClQJMmTZyWJ02apMmTJ19ynxEjRmjHjh1av359nutPnjypW265RU2aNLlsX4XNg1Zzaej29/eXu7u7kpOTndqTk5PzvP4+ISFBv/32m3r16uVos9vtkiQPDw/t3r1b9evXz7VfvXr15O/vr7179+b5TR4/frxiYmIcywcPHsz1iwIAAIBLO123k+wV/VxdBlCuuZ1OKfUfcO3cuVMhISGO5cuNco8cOVIfffSR1q1bp1q1auVan5aWph49esjHx0crVqxQhQoVClXP5fKg1Vwauj09PdW6dWvFxcU5Hvtlt9sVFxenkSNH5tq+cePG+vHHH53aHn/8caWlpem5555T7dq18zzOgQMHdPz4cdWsWTPP9Rdf7nDhpRAAAAAoGHtFP9kr5381IoCrg4+Pj6pWrXrZ7YwxGjVqlFasWKH4+HjVrVs31zYnT55UdHS0vLy89L///U/e3t6FrudyedBqLr+8PCYmRoMG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lJvbXwPyGRkZ+ve//60DBw6oYsWKaty4sV577TX169dPkuTu7q7t27dr6dKlSklJUXBwsLp3765p06YVy70EAAAAAIAr9/3336tr166O5Zx5tgYNGqQlS5ZIkt566y0ZY/INzQkJCTp27Jhj+cCBAxowYICOHz+uGjVqqEOHDvr2229Vo0YN607kMmzGGOOyo5dSBw4cUO3atfX777+rVq1ari4HAACHX375RcOHD2eGbwBAqVMeclS1atVks9lytdtsNnl7eys8PFyDBw92XJldEC4f6QYAAAAAoDSYOHGiZsyYoZ49e6pt27aSpE2bNmnVqlUaMWKE9u3bp/vvv1/nz5/XsGHDCtQnoRsAAAAAAEnr16/X9OnTdd999zm1L1y4UJ9//rnee+89RURE6Pnnny9w6C7S7OUpKSl66aWXNH78eJ04cUKStGXLFh08eLAo3QEAAAAA4HKfffaZoqKicrV369ZNn332mSTp5ptv1q+//lrgPgsdurdv366GDRtq5syZmj17tlJSUiRJ77//vsaPH1/Y7gAAAAAAKBWqV6+uDz/8MFf7hx9+qOrVq0vKntzbx8enwH0W+vLymJgYDR48WLNmzXI60M0336x//OMfhe0OAAAAAIBSYcKECbr//vu1Zs0axz3d3333nT755BMtWLBAkrR69Wp17ty5wH0WOnR/9913WrhwYa72kJAQJSUlFbY7AAAAAABKhWHDhqlJkyaaO3eu3n//fUlSo0aNtHbtWt1www2SpAcffLBQfRY6dHt5eenkyZO52n/55ReXPvsMAAAAAIAr1b59e7Vv377Y+iv0Pd233Xabpk6dqnPnzknKfl5ZYmKiHnnkEfXt27fYCgMAAAAAwFXOnDmjkydPOr2KotCh++mnn1Z6eroCAgJ0+vRpde7cWeHh4fLx8dGMGTOKVAQAAAAAAK526tQpjRw5UgEBAapcubKqVavm9CqKQl9e7uvrq9WrV+vrr7/Wtm3blJ6eruuuuy7PadUBAAAAACgrHnroIa1Zs0bz58/XPffco3nz5ungwYNauHChnnzyySL1WejQnaO4r3MHAAAAAMCVPvzwQ7366qvq0qWLhgwZoo4dOyo8PFyhoaF6/fXXdffddxe6z0JfXv6f//xHzz//fK72uXPnasyYMYUuAAAAAACA0uDEiROqV6+eJKlq1ao6ceKEJKlD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6GjHPt26dVOfPn0cofpy+fJyVq5cqeXLl+tvf/ub01wqTZs2VUJCQpHOs9Che9iwYRo9erQWL14sm82mQ4cOacOGDRo7dqwmTJhQ6AL69euno0ePauLEiUpKSlLLli21atUqx83viYmJcrvg0/uMjAz9+9//1oEDB1SxYkU1btxYr732mvr16+fY5uGHH1ZGRoaGDx+ulJQUdejQQatWrZK3t3eh6wMAwOVs2Y8Fc/vzMWE5z+Y2NrfswE3oBgCUQd9//726du3qWM655XfQoEGaP3++tm/frqVLlyolJUXBwcHq3r27pk2b5nSVckJCgo4dO+ZYvly+vJyjR48qICAgV3tGRkbeE5oWgM2YP//lLiBjjJ544gnFxsbq1KlTkrIvzx47dqymTZtWpCJKmwMHDqh27dr6/fffVatWLVeXAwCW+OWXXzR8+HBlNLmNy8vLkgv/2SZslxluGcdUeef/tGjRIjVs2NDV5QCAJcpDjurUqZP+/ve/a9SoUfLx8dH27dtVt25djRo1Snv27NGqVasK3WehR7ptNpsee+wxPfTQQ9q7d6/S09PVpEkTValSpdAHBwAAhUTQBgDAMk888YR69uypnTt36vz583ruuee0c+dOffPNN1q7dm2R+iz0rCuvvfaaTp06JU9PTzVp0kRt27YlcAMAAAAAyrwOHTpo27ZtOn/+vJo3b67PP/9cAQEB2rBhg1q3bl2kPgs90v3AAw/ovvvu02233aZ//vOfio6OzvPB5AAAAAAAlBU5T706e/asnnjiCdWoUaNY+i30SPfhw4f11ltvyWaz6a677lLNmjU1YsQIffPNN8VSEAAAAAAAJWnr1q1q3LixevTooV69eik8PFyfffZZsfRd6NDt4eGhW2+9Va+//rqOHDmiZ599Vr/99pu6du2q+vXrF0tRAAAAAACUlEceeUR169bV+vXrtXnzZnXr1q3Az/a+nEJfXn6hSpUqKTo6Wn/88Yf279+vn3/+uViKAgAAAACgpGzevFmff/65rrvuOknS4sWLVb16dZ08eVJVq1a9or4LPdItSadOndLrr7+um2++WSEhIZozZ4769Omjn3766YqKAQAAAACgpJ04ccLpMWd+fn6qXLmyjh8/fsV9F3qku3///vroo49UqVIl3XXXXZowYYLatWt3xYUAAAAAAOAqO3fuVFJSkmPZGKOff/5ZaWlpjraIiIhC91vo0O3u7q63336bWcsBAAAAAOVGt27dZIxxarv11ltls9lkjJHNZlNWVlah+y106H799dcLfRAAAAAAAEqrffv2WdZ3gUL3888/r+HDh8vb21vPP//8Jbf9z3/+UyyFAQAAAABQEkJDQy3ru0Ch+9lnn9Xdd98tb29vPfvss/luZ7PZCN0AAAAAAPypQKH7wqF2K4fdAQAAAAAoT4r0yDAAAAAAAHB5hQrdGRkZmjhxopo1a6YqVarIx8dHERERmjp1qk6dOmVVjQAAAAAAlEkFnr387Nmz6ty5s3bs2KGePXuqV69ejueWzZgxQ59++qnWrVunChUqWFkvAAAAAACWmDRpku69995inVitwKF7/vz5OnDggLZt26ZGjRo5rdu1a5e6dOmiBQsWaNSoUcVWHAAAAAAAJeWDDz7QjBkz1LlzZw0dOlR9+/aVl5fXFfVZ4MvL33//fU2YMCFX4Jakxo0b67HHHtO77757RcUAAAAAAOAqW7du1XfffaemTZtq9OjRCgoK0v3336/vvvuuyH0WOHTv3LlTXbp0yXd9165dtXPnziIXAgAAAACAq7Vq1UrPP/+8Dh06pJdfflkHDhxQ+/btFRERoeeee06pqamF6q/AoTslJUXXXHNNvuuvueaaQh8cAAAAAIDSyBijc+fO6ezZszLGqFq1apo7d65q166t5cuXF7ifAoduu90ud3f3/Dtyc1NWVlaBDwwAAAAAQGmzefNmjRw5UjVr1tQDDzygVq1a6eeff9batWu1Z88ezZgxQ//5z38K3F+BJ1Izxqhbt27y8Mh7l/Pnzxf4oACA0sPtDFcpAVbjfQYAZUPz5s21a9cude/eXS+//LJ69eqVa/B5wIABGj16dIH7LHDonjRp0mW36du3b4EPDABwLV9fX1Xw9JJ+XevqUoCrQgVPL/n6+rq6DADAJdx111269957FRISku82/v7+stvtBe7TZowxxVFceXLgwAHVrl1bv//+u2rVquXqcgDAMsnJyczHUcbs379fM2bM0GOPPVaszxCF9Xx9fRUYGOjqMgDAMuUtR+VEZZvNdkX9FHikGwBQ/gQGBhICyqjQ0FA1bNjQ1WUAAFDuvPzyy3r22We1Z88eSVKDBg00ZswY/etf/ypSf4RuAAAAAAAkTZw4Uc8884xGjRqldu3aSZI2bNigBx54QImJiZo6dWqh+yR0AwAAAAAgaf78+XrxxRc1YMAAR9ttt92miIgIjRo1qkihu8CPDAMAAAAAoDw7d+6c2rRpk6u9devWRX5iV7GF7gMHDmj48OHF1R0AAAAAACXqnnvu0fz583O1L1q0SHfffXeR+iy2y8uPHz+ul19+WYsWLSquLgEAAAAAsFRMTIzja5vNppdeekmff/65/va3v0mSNm7cqMTERA0cOLBI/XNPNwAAAADgqvXDDz84Lbdu3VqSlJCQICn7udz+/v766aefitQ/oRsAAAAAcNVas2aNpf0zkRoAAAAAABd58803lZGRccX9FHik+4477rjk+pSUlCutBQAAAACAUuH//u//FBkZqXr16l1RPwUO3b6+vpddX9QbywEAAAAAKE2MMcXST4FD9yuvvHLZbdLT06+oGAAAAAAAStLJkydVtWpVy/ov8D3dzz777CXXp6WlKTo6+ooLAgAAAACgpFSrVk1HjhyRJN14442OW6c//fRTBQcHX3H/BQ7djz76qF599dU816Wnp6tHjx46fvz4FRcEAAAAAEBJqVKliiPLxsfH69y5c5KkDh06yNvb+4r7L/Dl5cuWLdM999wjPz8/3XbbbY72jIwM9ejRQ0ePHtXatWuvuCAAAAAAAEpKVFSUunbtqmuvvVaS1KdPH3l6eua57Zdfflno/gscuu+8806lpKRowIAB+vjjj9WlSxdH4E5OTtbatWtVs2bNQhcAAAAAAICrvPbaa1q6dKkSEhK0du1aNW3aVJUqVSq2/gscuiXpX//6l06cOKHbb79dH3zwgSZOnKhDhw5p7dq1xXKtOwAAAAAAJencuXO67777JEnff/+9Zs6cKT8/v2Lrv1ChW5IefvhhnThxQt26dVNYWJji4+NVq1atYisIAAAAAICSUq1aNR0+fFgBAQGy2WzF3n+BQ/cdd9zhtFyhQgX5+/tr9OjRTu3vv/9+8VQGAAAAAIDFciZSCwgI0Nq1ax0TqRWXAoduX19fp+UBAwYUayEAAAAAAJS0CydSM8a4biK1V155pdCdAwAAAABQmpWqidQAAAAAAChPKlasaOlEam7F1tMVmDdvnsLCwuTt7a3IyEht2rQp321ffPFFdezYUdWqVVO1atUUFRWVa/vBgwfLZrM5vXr06GH1aQAAAAAACmjdunXq1auXgoODZbPZtHLlSse6c+fO6ZFHHlHz5s1VuXJlBQcHa+DAgTp06NAl+5w8eXKuLNi4ceMC17RmzRr5+fnp2LFjOnbsWFFPzYnLQ/fy5csVExOjSZMmacuWLWrRooWio6N15MiRPLePj4/XgAEDtGbNGm3YsEG1a9dW9+7ddfDgQaftevToocOHDzteb775ZkmcDgAAAACgADIyMtSiRQvNmzcv17pTp05py5YtmjBhgrZs2aL3339fu3fv1m233XbZfps2beqUBdevX1+gelJSUjRixAj5+/srMDBQgYGB8vf318iRI5WSklLY03Nw+eXlzzzzjIYNG6YhQ4ZIkhYsWKCPP/5Yixcv1rhx43Jt//rrrzstv/TSS3rvvfcUFxengQMHOtq9vLwUFBRkbfEAAAAAgCLp2bOnevbsmec6X19frV692qlt7ty5atu2rRITE1WnTp18+/Xw8Ch0Fjxx4oTatWungwcP6u6779a1114rSdq5c6eWLFmiuLg4ffPNN6pWrVqh+pVcPNJ99uxZbd68WVFRUY42Nzc3RUVFacOGDQXq49SpUzp37pyqV6/u1B4fH6+AgAA1atRI999/v44fP16stQMAAAAASk5qaqpsNttl77fes2ePgoODVa9ePd19991KTEy8bN9Tp06Vp6enEhIStHDhQo0ZM0ZjxozRokWLtHfvXlWoUEFTp04tUt0uHek+duyYsrKyFBgY6NQeGBioXbt2FaiPRx55RMHBwU7BvUePHrrjjjtUt25dJSQk6NFHH1XPnj21YcMGubu75+ojMzNTmZmZjuW0tLQinhEAoDQ4c+ZMgf6BLYv279/v9Gd5VKdOHXl7e7u6DABAEaWlpenkyZOOZS8vL3l5eV1Rn2fOnNEjjzyiAQMGqGrVqvluFxkZqSVLlqhRo0Y6fPiwpkyZoo4dO2rHjh3y8fHJd7+VK1dq4cKFubKpJAUFBWnWrFm677779Oyzzxa6dpdfXn4lnnzySb311luKj493+se5f//+jq+bN2+uiIgI1a9fX/Hx8erWrVuufmJjYzVlypQSqRkAYL3ExEQNHz7c1WVYasaMGa4uwTKLFi1Sw4YNXV0GAKCImjRp4rQ8adIkTZ48ucj9nTt3TnfddZeMMZo/f/4lt73wcvWIiAhFRkYqNDRUb7/9toYOHZrvfocPH1bTpk3zXd+sWTMlJSUVvni5OHT7+/vL3d1dycnJTu3JycmXvQZ/9uzZevLJJ/XFF18oIiLiktvWq1dP/v7+2rt3b56he/z48YqJiXEsHzx4MNcvCgCg7KhTp44WLVrk6jJQRJe6Tw8AUPrt3LlTISEhjuUrGeXOCdz79+/Xl19+eclR7rz4+fmpYcOG2rt37yW38/f312+//aZatWrluX7fvn25bmkuKJeGbk9PT7Vu3VpxcXHq3bu3JMlutysuLk4jR47Md79Zs2ZpxowZ+uyzz9SmTZvLHufAgQM6fvy4atasmef6iy93uPBSCABA2ePt7c1IKQAALuLj41PocJyXnMC9Z88erVmzRtdcc02h+0hPT1dCQoLuueeeS24XHR2txx57TKtXr5anp6fTuszMTE2YMKHIj6F2+eXlMTExGjRokNq0aaO2bdtqzpw5ysjIcMxmPnDgQIWEhCg2NlaSNHPmTE2cOFFvvPGGwsLCHEP8VapUUZUqVZSenq4pU6aob9++CgoKUkJCgh5++GGFh4crOjraZecJAAAAAPhLenq60wj0vn37tHXrVlWvXl01a9bUnXfeqS1btuijjz5SVlaWI/tVr17dEYy7deumPn36OAZtx44dq169eik0NFSHDh3SpEmT5O7urgEDBlyylqlTp6pNmzZq0KCBRowYocaNG8sYo59//lkvvPCCMjMztWzZsiKdp8tDd79+/XT06FFNnDhRSUlJatmypVatWuW4gT0xMVFubn9Nsj5//nydPXtWd955p1M/OfcJuLu7a/v27Vq6dKlSUlIUHBys7t27a9q0aVd88z4AAAAAoHh8//336tq1q2M555bfQYMGafLkyfrf//4nSWrZsqXTfmvWrFGXLl0kSQkJCTp27Jhj3YEDBzRgwAAdP35cNWrUUIcOHfTtt9+qRo0al6ylVq1a2rBhg/79739r/PjxMsZIkmw2m2666SbNnTtXtWvXLtJ52kxOb3A4cOCAateurd9//z3fa/oBAAAAAH8pLznqjz/+0J49eyRJ4eHhRb6XO4fLR7oBAEAhXPhZuc3mujoAACinqlWrprZt2xZbf4RuAADKAmMkuz37lcPNLftF+AYAoNQidAMAUNoZI2VlZf9ps2W/ckK4MZK7O8EbAIBSyu3ymwAAAJfKCdcXjmrbbNnLOeEbAACUSoRuAABKs5xQnd9Its32VygHAAClDqEbAICy4FKhGwAA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AAAAsAihGwAAAAAAixC6AQAAAACwCKEbAAAAAACLELoBACjHunTpojFjxri6DAAArlqEbgAASsCCBQvk4+Oj8+fPO9rS09NVoUIFdenSxWnb+Ph42Ww2JSQklHCVAACguBG6AQAoAV27dlV6erq+//57R9tXX32loKAgbdy4UWfOnHG0r1mzRnXq1FH9+vVdUSoAAChGhG4AAEpAo0aNVLNmTcXHxzva4uPjdfvtt6tu3br69ttvndq7du0qu92u2NhY1a1bVxUrVlSLFi307rvvOvW7Y8cO9ezZU1WqVFFgYKDuueceHTt2LN86Pv74Y/n6+ur1118v9nMEAAC5EboBACghXbt21Zo1axzLa9asUZcuXdS5c2dH++nTp7Vx40Z17dpVsbGxevXVV7VgwQL99NNPeuCBB/TPf/5Ta9eulSSlpKToxhtvVKtWrfT9999r1apVSk5O1l133ZXn8d944w0NGDBAr7/+uu6++27rTxgAAMjD1QUAAHC16Nq1q8aMGaPz58/r9OnT+uGHH9S5c2edO3dOCxYskCRt2LBBmZmZ6tKli5o0aaIvvvhC7dq1kyTVq1dP69ev18KFC9W5c2fNnTtXrVq10hNPPOE4xuLFi1W7dm398ssvatiwoaN93rx5euyxx/Thhx+qc+fOJXviAABcxQjdAACUkC5duigjI0Pfffed/vjjDzVs2FA1atRQ586dNWTIEJ05c0bx8fGqV6+e0tPTderUKd10001OfZw9e1atWrWSJG3btk1r1qxRlSpVch0rISHBEbrfffddHTlyRF9//bWuv/56608UAAA4ELoBACgh4eHhqlWrltasWaM//vjDMeIcHBys2rVr65tvvtGaNWt04403Kj09XVL2PdghISFO/Xh5eUnKnv28V69emjlzZq5j1axZ0/F1q1attGXLFi1evFht2rSRzWaz6hQBAMBFCN0AAJSgrl27Kj4+Xn/88YceeughR3unTp306aefatOmTbr//vvVpEkTeXl5KTExMd/Lwa+77jq99957CgsLk4dH/v+k169fX08//bS6dOkid3d3zZ07t9jPCwAA5I2J1AAAKEFdu3bV+vXrtXXrVqcw3blzZy1cuFBnz55V165d5ePjo7Fjx+qBBx7Q0qVLlZCQoC1btui///2vli5dKkkaMWKETpw4oQEDBui7775TQkKCPvvsMw0ZMkRZWVlOx23YsKHWrFmj9957T2PGjCnJUwYA4KrGSDcAACWoa9euOn36tBo3bqzAwEBHe+fOnZWWluZ4tJgkTZs2TTVq1FBsbKx+/fVX+fn56brrrtOjjz4qKfuy9K+//lqPPPKIunfvrszMTIWGhqpHjx5yc8v9uXqjRo305ZdfOka8n3766ZI5aQAArmI2Y4xxdREAAAAAAJRHXF4OAAAAAIBFCN0AAAAAAFiE0A0AAAAAgEUI3QAAAAAAWITQDQAAAACARQjdAAAAAABYhNANAAAAAIBFCN0AAAAAAFiE0A0AAAAAgEUI3QAAAAAAWITQDQAAAACARQjdAAAAAABY5P8BuOFnE0nBsqwAAAAASUVORK5CYII=",
|
1966 |
+
"text/plain": [
|
1967 |
+
"<Figure size 1000x600 with 2 Axes>"
|
1968 |
+
]
|
1969 |
+
},
|
1970 |
+
"metadata": {},
|
1971 |
+
"output_type": "display_data"
|
1972 |
+
}
|
1973 |
+
],
|
1974 |
+
"source": [
|
1975 |
+
"import pandas as pd\n",
|
1976 |
+
"import matplotlib.pyplot as plt\n",
|
1977 |
+
"import seaborn as sns\n",
|
1978 |
+
"\n",
|
1979 |
+
"# Assuming you have your dataframe as 'df'\n",
|
1980 |
+
"# If not, you can create a sample dataframe like this:\n",
|
1981 |
+
"df = pd.DataFrame({\n",
|
1982 |
+
" 'week': [1, 1, 1, 2, 2, 2, 3, 3, 3],\n",
|
1983 |
+
" 'kl_divergence': [0.1, 0.2, 0.15, 0.3, 0.25, 0.35, 0.4, 0.45, 0.5],\n",
|
1984 |
+
" 'off_by_perc': [5, 10, 7, 15, 12, 18, 20, 22, 25]\n",
|
1985 |
+
"})\n",
|
1986 |
+
"\n",
|
1987 |
+
"# Create the main figure and axis\n",
|
1988 |
+
"fig, ax1 = plt.subplots(figsize=(10, 6))\n",
|
1989 |
+
"\n",
|
1990 |
+
"# Create the boxplot using seaborn\n",
|
1991 |
+
"sns.boxplot(x='week', y='kl_divergence', data=df, ax=ax1)\n",
|
1992 |
+
"\n",
|
1993 |
+
"# Set labels and title for the main axis\n",
|
1994 |
+
"ax1.set_xlabel('Week')\n",
|
1995 |
+
"ax1.set_ylabel('KL Divergence')\n",
|
1996 |
+
"ax1.set_title('KL Divergence Boxplot with Off-by Percentage')\n",
|
1997 |
+
"\n",
|
1998 |
+
"# Create a secondary y-axis\n",
|
1999 |
+
"ax2 = ax1.twinx()\n",
|
2000 |
+
"\n",
|
2001 |
+
"# Plot the off_by_perc values on the secondary y-axis\n",
|
2002 |
+
"for i, week in enumerate(df['week'].unique()):\n",
|
2003 |
+
" off_by_perc = df[df['week'] == week]['off_by_perc']\n",
|
2004 |
+
" ax2.scatter([i] * len(off_by_perc), off_by_perc, color='red', alpha=0.01)\n",
|
2005 |
+
"\n",
|
2006 |
+
"# Set label for the secondary y-axis\n",
|
2007 |
+
"ax2.set_ylabel('Off-by Percentage')\n",
|
2008 |
+
"\n",
|
2009 |
+
"# Adjust the layout and display the plot\n",
|
2010 |
+
"plt.tight_layout()\n",
|
2011 |
+
"plt.show()"
|
2012 |
+
]
|
2013 |
}
|
2014 |
],
|
2015 |
"metadata": {
|
notebooks/divergence.ipynb
ADDED
File without changes
|
tabs/market_plots.py
CHANGED
@@ -3,6 +3,8 @@ import gradio as gr
|
|
3 |
import plotly.express as px
|
4 |
import plotly.graph_objects as go
|
5 |
from plotly.subplots import make_subplots
|
|
|
|
|
6 |
|
7 |
|
8 |
def plot_kl_div_per_market(closed_markets: pd.DataFrame) -> gr.Plot:
|
@@ -29,6 +31,7 @@ def plot_kl_div_per_market(closed_markets: pd.DataFrame) -> gr.Plot:
|
|
29 |
yaxis_title="Kullback–Leibler divergence",
|
30 |
legend=dict(yanchor="top", y=0.5),
|
31 |
)
|
|
|
32 |
fig.update_xaxes(tickformat="%b %d\n%Y")
|
33 |
|
34 |
return gr.Plot(
|
@@ -36,6 +39,52 @@ def plot_kl_div_per_market(closed_markets: pd.DataFrame) -> gr.Plot:
|
|
36 |
)
|
37 |
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
def plot_kl_div_per_market2(closed_markets: pd.DataFrame) -> gr.Plot:
|
40 |
|
41 |
# adding the total
|
@@ -59,7 +108,7 @@ def plot_kl_div_per_market2(closed_markets: pd.DataFrame) -> gr.Plot:
|
|
59 |
y=final_markets[final_markets["market_creator"] == creator][
|
60 |
"kl_divergence"
|
61 |
],
|
62 |
-
name=
|
63 |
boxmean=True,
|
64 |
marker_color={
|
65 |
"pearl": "purple",
|
@@ -70,37 +119,28 @@ def plot_kl_div_per_market2(closed_markets: pd.DataFrame) -> gr.Plot:
|
|
70 |
secondary_y=False,
|
71 |
)
|
72 |
fig.add_trace(
|
73 |
-
go.
|
74 |
x=final_markets[final_markets["market_creator"] == creator][
|
75 |
"month_year_week"
|
76 |
],
|
77 |
y=final_markets[final_markets["market_creator"] == creator][
|
78 |
"off_by_perc"
|
79 |
],
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
"pearl": "pink",
|
84 |
-
"quickstart": "yellow",
|
85 |
-
"all": "lightgreen",
|
86 |
-
}[creator],
|
87 |
),
|
88 |
secondary_y=True,
|
89 |
)
|
90 |
# Update layout
|
91 |
fig.update_layout(
|
92 |
xaxis_title="Markets closing Week",
|
93 |
-
legend=dict(yanchor="top", y=0.5, xanchor="left", x=-0.5),
|
|
|
94 |
boxmode="group",
|
95 |
width=1000, # Adjusted for better fit on laptop screens
|
96 |
height=600, # Adjusted for better fit on laptop screens
|
97 |
)
|
98 |
-
# Calculate the range for both axes
|
99 |
-
# derived_min, derived_max = (
|
100 |
-
# final_markets["off_by"].min(),
|
101 |
-
# final_markets["off_by"].max(),
|
102 |
-
# )
|
103 |
-
|
104 |
# Update y-axes
|
105 |
fig.update_yaxes(
|
106 |
title_text="Kullback–Leibler divergence", secondary_y=False, side="left"
|
@@ -109,7 +149,6 @@ def plot_kl_div_per_market2(closed_markets: pd.DataFrame) -> gr.Plot:
|
|
109 |
title_text="Off by percentage between probabilities",
|
110 |
secondary_y=True,
|
111 |
side="right",
|
112 |
-
# range=[derived_min, derived_max],
|
113 |
)
|
114 |
|
115 |
# Update x-axis
|
|
|
3 |
import plotly.express as px
|
4 |
import plotly.graph_objects as go
|
5 |
from plotly.subplots import make_subplots
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
import seaborn as sns
|
8 |
|
9 |
|
10 |
def plot_kl_div_per_market(closed_markets: pd.DataFrame) -> gr.Plot:
|
|
|
31 |
yaxis_title="Kullback–Leibler divergence",
|
32 |
legend=dict(yanchor="top", y=0.5),
|
33 |
)
|
34 |
+
|
35 |
fig.update_xaxes(tickformat="%b %d\n%Y")
|
36 |
|
37 |
return gr.Plot(
|
|
|
39 |
)
|
40 |
|
41 |
|
42 |
+
def plot_kl_div_with_off_by(closed_markets: pd.DataFrame) -> gr.Plot:
|
43 |
+
# adding the total
|
44 |
+
all_markets = closed_markets.copy(deep=True)
|
45 |
+
all_markets["market_creator"] = "all"
|
46 |
+
|
47 |
+
# merging both dataframes
|
48 |
+
final_markets = pd.concat([closed_markets, all_markets], ignore_index=True)
|
49 |
+
final_markets = final_markets.sort_values(by="opening_datetime", ascending=True)
|
50 |
+
|
51 |
+
# Create the main figure and axis
|
52 |
+
fig, ax1 = plt.subplots(figsize=(10, 6))
|
53 |
+
|
54 |
+
# Create the boxplot using seaborn
|
55 |
+
sns.boxplot(
|
56 |
+
data=final_markets,
|
57 |
+
x="month_year_week",
|
58 |
+
y="kl_divergence",
|
59 |
+
ax=ax1,
|
60 |
+
hue="market_creator",
|
61 |
+
)
|
62 |
+
|
63 |
+
# Set labels and title for the main axis
|
64 |
+
ax1.set_xlabel("Week")
|
65 |
+
ax1.set_ylabel("KL Divergence")
|
66 |
+
ax1.set_title("KL Divergence Boxplot with Off-by Percentage")
|
67 |
+
|
68 |
+
# Create a secondary y-axis
|
69 |
+
ax2 = ax1.twinx()
|
70 |
+
|
71 |
+
# Plot the off_by_perc values on the secondary y-axis
|
72 |
+
for i, week in enumerate(closed_markets["month_year_week"].unique()):
|
73 |
+
off_by_perc = closed_markets[closed_markets["month_year_week"] == week][
|
74 |
+
"off_by_perc"
|
75 |
+
]
|
76 |
+
ax2.scatter([i] * len(off_by_perc), off_by_perc, color="red", alpha=0.01)
|
77 |
+
|
78 |
+
# Set label for the secondary y-axis
|
79 |
+
ax2.set_ylabel("Off-by Percentage")
|
80 |
+
|
81 |
+
# Adjust the layout and display the plot
|
82 |
+
plt.tight_layout()
|
83 |
+
return gr.Plot(
|
84 |
+
value=fig,
|
85 |
+
)
|
86 |
+
|
87 |
+
|
88 |
def plot_kl_div_per_market2(closed_markets: pd.DataFrame) -> gr.Plot:
|
89 |
|
90 |
# adding the total
|
|
|
108 |
y=final_markets[final_markets["market_creator"] == creator][
|
109 |
"kl_divergence"
|
110 |
],
|
111 |
+
name=creator,
|
112 |
boxmean=True,
|
113 |
marker_color={
|
114 |
"pearl": "purple",
|
|
|
119 |
secondary_y=False,
|
120 |
)
|
121 |
fig.add_trace(
|
122 |
+
go.Scatter(
|
123 |
x=final_markets[final_markets["market_creator"] == creator][
|
124 |
"month_year_week"
|
125 |
],
|
126 |
y=final_markets[final_markets["market_creator"] == creator][
|
127 |
"off_by_perc"
|
128 |
],
|
129 |
+
opacity=0.01,
|
130 |
+
showlegend=False,
|
131 |
+
hoverinfo="skip",
|
|
|
|
|
|
|
|
|
132 |
),
|
133 |
secondary_y=True,
|
134 |
)
|
135 |
# Update layout
|
136 |
fig.update_layout(
|
137 |
xaxis_title="Markets closing Week",
|
138 |
+
# legend=dict(yanchor="top", y=0.5, xanchor="left", x=-0.5),
|
139 |
+
legend=dict(yanchor="top", y=0.5),
|
140 |
boxmode="group",
|
141 |
width=1000, # Adjusted for better fit on laptop screens
|
142 |
height=600, # Adjusted for better fit on laptop screens
|
143 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
# Update y-axes
|
145 |
fig.update_yaxes(
|
146 |
title_text="Kullback–Leibler divergence", secondary_y=False, side="left"
|
|
|
149 |
title_text="Off by percentage between probabilities",
|
150 |
secondary_y=True,
|
151 |
side="right",
|
|
|
152 |
)
|
153 |
|
154 |
# Update x-axis
|