0

I have a dataframe containing lists of elements like this: enter image description here

I have 10 stimulus values and 16 trials per stimulus. The lists contain spike amplitude values of a spike train. So if there are e.g. two values 33 and 34 in a list, my algorithm found two spikes with 33mV and 34mV. I want to plot all of those values to get an impression of my data.

Currently I'm using these lines of code to get this plot

flatui = ["#9b59b6", "#3498db", "#95a5a6", "#e74c3c", "#34495e", "#2ecc71"]
g = sns.FacetGrid(df, col='stimulus', col_wrap=5, sharey=True, sharex=True)
g.map(sns.swarmplot, 'trial', 'data', edgecolor="black", linewidth=.9, palette=flatui)
g.set_axis_labels('trials', '[ms]')

enter image description here

Obviously it doesn't plot all values but only one per list (the mean? the first? I don't know). Can you help me to plot all of them at once?


Build my dataframe

trial_vec       = np.tile(np.arange(16)+1, 10)     
stimulus_vec    = np.repeat([-2., -1.75, -1., -0.75, -0.5,  0.5,  1.,  1.25,  1.75,  2.5 ], 16)                  
data_vec        = np.random.randint(0, 16, size=160)
spi_amp         = pd.DataFrame({'trial': trial_vec, 'stimulus': stimulus_vec, 'data': data_vec}).astype('object')
spi_amp["data"] = [np.random.rand(4).tolist() for i in range(160)]
spi_amp
Svenno Nito
  • 635
  • 1
  • 6
  • 22

1 Answers1

2

Thinking about it, I guess the only way to accomplish what you want is to convert the dataframe with the lists in one column into a long form, such that each list entry has its own row in the dataframe. See this question on a possible way of doing this.

Using the presented method on the data from the question gives you:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

trial_vec       = np.tile(np.arange(16)+1, 10)     
stimulus_vec    = np.repeat([-2., -1.75, -1., -0.75, -0.5,  0.5,  1.,  1.25,  1.75,  2.5 ], 16)                  
data_vec        = np.random.randint(0, 16, size=160)
df         = pd.DataFrame({'trial': trial_vec, 'stimulus': stimulus_vec}).astype('object')
df["data"] = [np.random.rand(4).tolist() for i in range(160)]

# convert dataframe to long form
df2 = df.set_index(['trial', 'stimulus'])['data'].apply(pd.Series).stack()
df2 = df2.reset_index()
df2.columns = ['trial', 'stimulus','pos','data']

# the plotting code stays the same
flatui = ["#9b59b6", "#3498db", "#95a5a6", "#e74c3c", "#34495e", "#2ecc71"]
g = sns.FacetGrid(df2, col='stimulus', col_wrap=5, sharey=True, sharex=True)
g.map(sns.swarmplot, 'trial', 'data', edgecolor="black", linewidth=.9, palette=flatui)
g.set_axis_labels('trials', '[ms]')

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712