2

I hava a dataframe which looks like that:

            Value   Std         Reciever type
Station ID                                   
ABMF        3.588 0.492         TRIMBLE NETR9
AIRA        8.820 0.256         TRIMBLE NETR9
AREG        7.306 0.356         TRIMBLE NETR9
BRST        6.712 0.166         TRIMBLE NETR9
BRUX        3.151 0.151        SEPT POLARX4TR
          ...   ...                   ...
WTZR       12.374 0.158    LEICA GRX1200+GNSS
WTZZ        1.906 0.179  JAVAD TRE_G3TH DELTA
WUH2        4.422 0.534  JAVAD TRE_G3TH DELTA
ZIM2       11.244 0.171         TRIMBLE NETR5
ZIM3       11.971 0.185         TRIMBLE NETR9

[80 rows x 3 columns]

and I'm trying to create visualization based on aggregation like that:

df = (df.groupby(by=['Station ID'])
              .agg({'Value': np.average, 'Std': np.average, 'Reciever type': 'first'})
              )
            dcb_plot = plt.figure(figsize=(16,9))
            plt.title('Receiver Code Biases for {} station(s) ({})'.format(station, year))
            plt.xlabel('Station(s)')
            plt.ylabel('DCB in ns')
            plt.errorbar(df.index, df['Value'], yerr=df['Std'], marker='o', fmt='o', ms=5, capsize=5, elinewidth=1)  
            ax = plt.gca()
            ax.axes.xaxis.set_ticklabels([])
            ax.yaxis.set_minor_locator(AutoMinorLocator())
            ax.tick_params(which='major', length=8)
            ax.tick_params(which='minor', length=4, color='r')

right now I've achieved someting like this: enter image description here

and i want to create colormap based on values inside Reciever type column (colored errorbars would be nice too). How can I do that? For better understanding, this is my desired output: enter image description here

1 Answers1

0

The key is to generate colors form colormaps. I dont use df here, but it should be very easy to adapt to you data.

from sklearn.datasets import make_blobs
import numpy as np
import matplotlib.pyplot as plt

n_samples = 100
random_state = 170
X, y = make_blobs(n_samples=n_samples, random_state=random_state, centers=3)
names = {0:'a', 1:'b', 2:'c'}
all_names = np.array([names[e] for e in y])
n = len(np.unique(all_names))
# this is how your map colors
colors = plt.cm.Spectral(np.arange(n)/np.arange(n).max())

fig, ax = plt.subplots(1, 1, figsize=(7.2, 7.2))
for i, e in enumerate(np.unique(all_names)):
    mask = all_names == e
    ax.errorbar(X[:, 0][mask], X[:, 1][mask], yerr=0.5, marker='o', fmt='o', ms=5, capsize=5, elinewidth=1, label=e, c=colors[i])
ax.legend()

enter image description here

Jiadong
  • 1,822
  • 1
  • 17
  • 37
  • I get it, but how can i implement it to dataframe? Especially in `ax.errorbar` part? – Mateusz Piskorski Sep 23 '20 at 12:18
  • label = e is what you should pass from df. – Jiadong Sep 23 '20 at 12:22
  • Sorry, I still dont get it, can you refer to my example qgiven in question? – Mateusz Piskorski Sep 23 '20 at 12:27
  • For example label = 'TRIMBLE NETR9', but you have to do it an automatic way. First `all_names` should be array of all your Receiver type in your df. Then everything just works fine. Try print some result when you get confused. – Jiadong Sep 23 '20 at 12:32
  • and i have done that, for me this part is confusing: `X[:, 0][mask], X[:, 1][mask]`. How to rewrite it with dataframe? – Mateusz Piskorski Sep 23 '20 at 12:38
  • X[:, 0] just x values, and X[:, 1] are y values, they are numpy array. Are these not corresponding to your df.index, df['Value'] ? – Jiadong Sep 23 '20 at 12:46
  • they are and when i do this: `ax.errorbar(df.index[e], df['Value'][e], yerr=df['Std'], marker='o', fmt='o', ms=5, capsize=5, elinewidth=1, label=e, c=colors[i])` i get this: `IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices` – Mateusz Piskorski Sep 23 '20 at 12:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/221938/discussion-between-ted930511-and-mateusz-piskorski). – Jiadong Sep 23 '20 at 12:50