0

I have a dataframe that looks like this:

x | y | value
10  20    0.1
20  5     0.2
30  15    0.7
40  10    0.5

I want to plot these values in a scatter plot and the color of each marker should be a color map calculated from the value column. The values go from 0 to 1.

Should I create a custom color map? How do I use it then?

EDIT:

Since some of the rows are not relevant to the scatter plot, I am plotting the relevant rows by iterating through the dataset:

for i,row in df.iterrows():
    ax.scatter(df.iloc[i]['y'], df.iloc[i]['x'], c= row['value'] , cmap='jet', edgecolors = 'r', linewidths = '1', marker='p', s=80)

Thank you! Kind Regards

JohanC
  • 71,591
  • 8
  • 33
  • 66
vftw
  • 1,547
  • 3
  • 22
  • 51
  • Does this answer your question? [Scatter plot and Color mapping in Python](https://stackoverflow.com/questions/17682216/scatter-plot-and-color-mapping-in-python) – Pygirl Feb 04 '21 at 11:54
  • Something like `plt.scatter(df['x'], df['y'], c=df['value'], cmap='inferno')`? – JohanC Feb 04 '21 at 12:20
  • I tried that @JohanC but then I got this error `IndexError: tuple index out of range` – vftw Feb 04 '21 at 12:27
  • Updated the question with my current approach @JohanC – vftw Feb 04 '21 at 12:31
  • 1
    Not what JohanC suggested, though. Why would use iterrows? Tbh, you should nearly never use iterrows. – Mr. T Feb 04 '21 at 12:32
  • Because not all the rows are relevant and for some of them I need to check the previous and next row to plot them. Why shouldn't I use it @Mr.T? – vftw Feb 04 '21 at 12:33
  • This is not reflected by your question. I suggest providing an MCVE. P.S.: That y is plotted on the x-axis and vice versa is intentional, right? – Mr. T Feb 04 '21 at 12:34
  • Why is that? I need to know how to change the color based on a value. That value goes from 0 to 1 which should be translated to a color map – vftw Feb 04 '21 at 12:38
  • 1
    You could create a new dataframe with only the desired rows? Or you could create an array with the indices of the desired rows and use these as `plt.scatter(df['x'][ind], df['y'][ind], c=df['value'][ind], cmap='inferno')`. Also, it is strongly recommended [not to use `jet`](http://jakevdp.github.io/blog/2014/10/16/how-bad-is-your-colormap/) if you want to avoid strange highlights. – JohanC Feb 04 '21 at 12:38
  • Well, I can create the dataframe with the desired rows but I'd need to iterate through the whole df anyway. Basically, based on previous and next rows I decide the marker, size, edgecolors, that's why I chose this approach. I thought it would be easier to manage the color since value is normalized between 0 and 1 and that it would be possible to do something like `... c = 0.1, cmap = 'Reds' ` and that 0.1 is mapped to the respective color in the cmap. – vftw Feb 04 '21 at 12:46

1 Answers1

0

If you really need to go through the dataframe row by row, you could add vmin=0 and vmax=1 to the call to plt.scatter to let it know your color range.

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame({'x': np.random.uniform(0, 30, 50),
                   'y': np.random.uniform(0, 15, 50),
                   'value': np.random.uniform(0, 1, 50)})
for _, row in df.iterrows():
    plt.scatter(row['x'], row['y'], c=row['value'],
                cmap='Reds', vmin=0, vmax=1,
                edgecolors='r', linewidths=1, marker='p', s=80)
plt.colorbar()
plt.tight_layout()
plt.show()

example plot

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • I did exactly that and for `c=row['value'],` I get: `IndexError: tuple index out of range` – vftw Feb 04 '21 at 13:49
  • 1
    With the copy-pasted code provided by JohanC? Frequently, this kind of problem is caused by ancient matplotlib/pandas versions. What are your version numbers? – Mr. T Feb 04 '21 at 13:57
  • @LuísCosta The code should work in pandas 1.0. The current version is 1.2.1. Maybe the folllowing works for you? `for i in range(len(df)): plt.scatter(df['x'][i], df['y'][i], c=df['value'][i], cmap='inferno', ...)`. Anyway, it is highly recommended to upgrade. – JohanC Feb 04 '21 at 14:38
  • Is your question answered now? – JohanC Feb 11 '21 at 22:07