1

I have a Pandas database (below I am creating a random database to mimic mine).

I use Seaborn, facet-grid and scatterplot to plot the data the way I want : Epsilon1 as a function of no, I distinguish the data from the sub categories A and B using different subplots and colors. This part of the code works correctly.

Then I want that the user can click on any dot in order to display in the IPython console and in the status bar of the Matplotlib figure (as here) all the informations about this dot : that is to say all the values of the corresponding dataframe row: something like: 'no':5, 'Date':1997-12-15 03:50:41, 'A':A6, 'B':B4, 'Epsilon1':0.670635, 'Epsilon2':0.756461, 'Epsilon3':0.530825

I have made first tests using onpick event (not shown here) but all were unsuccessful. Actually I can't get by with the function onpick(event) because I do not understand why print(event.ind) gives me a list of integers...

Here is my code

import pandas as pd
import numpy as np 
import seaborn as sns
import random

# size of the database
n = 1000

nA = 6
nB = 5

no = np.arange(n)
date = np.random.randint(1e9, size=n).astype('datetime64[s]')
A = [''.join(['A',str(random.randint(1, nA))]) for j in range(n)]
B = [''.join(['B',str(random.randint(1, nB))]) for j in range(n)]
Epsilon1 = np.random.random_sample((n,))
Epsilon2 = np.random.random_sample((n,))
Epsilon3 = np.random.random_sample((n,))

data = pd.DataFrame({'no':no,
                     'Date':date,
                     'A':A,
                     'B':B,
                     'Epsilon1':Epsilon1,
                     'Epsilon2':Epsilon2,
                     'Epsilon3':Epsilon3})

def onpick(event):

    print(event.ind)

def plot_Epsilon1_seaborn():
    
    sns.set_theme()
    
    g = sns.FacetGrid(data, 
                      col="A", 
                      col_wrap=4,
                      hue='B',
                      hue_order=data['B'].sort_values().drop_duplicates().to_list(),
                      palette="viridis", 
                      col_order=data['A'].sort_values().drop_duplicates().to_list()) 
    g.map(sns.scatterplot,
          'no',
          'Epsilon1',
          picker=True)
    
    g.add_legend()
    
    g.fig.canvas.mpl_connect("pick_event", onpick)

if __name__ == '__main__':

    plot_Epsilon1_seaborn()
Julien M.
  • 35
  • 1
  • 8
  • I think this [answer](https://stackoverflow.com/a/61337574/7758804) – Trenton McKinney Jan 23 '23 at 18:40
  • @TrentonMcKinney Yes. I'm also currently developping a solution with mplcursors. Once found, I will post it on this page. However, here, I am rather looking for a solution which displays the informations in the IPython console and in the status bar of the Matplotlib figure. – Julien M. Jan 25 '23 at 08:38
  • See [Add legend to x, y coordinates on the status bar](https://stackoverflow.com/questions/66643653/add-legend-to-x-y-coordinates-on-the-status-bar) about how you can update the status bar with mplcursors instead of showing a popup. Anyway, you can't rely on seaborn's automatic sectioning of the data, you'll need your own splitting of the dataframe. Also, you seem to want to put a lot more information into the status bar than what normally fits there (this also depends on the window size). – JohanC Jan 25 '23 at 10:33
  • Using only Matplotlib, I have developed another code that plots the points of database. The data is plotted on several figures and subplots, and so is now more readable and I am closer to the point I want to reach: the user by putting the cursor over a point has access to all the information of the point, in particular the datetime. However, I have problem with datetime format. I posted this code [here](https://stackoverflow.com/questions/75398867/changing-the-format-of-coordinate-text-with-datetime-in-status-bar-of-a-matplo) – Julien M. Feb 09 '23 at 12:58

0 Answers0