Scatter Plot and Color Mapping in Python

Scatter plot and Color mapping in Python

Here is an example

import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(100)
y = np.random.rand(100)
t = np.arange(100)

plt.scatter(x, y, c=t)
plt.show()

Here you are setting the color based on the index, t, which is just an array of [1, 2, ..., 100].
Sample Image

Perhaps an easier-to-understand example is the slightly simpler

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(100)
y = x
t = x
plt.scatter(x, y, c=t)
plt.show()

Sample Image

Note that the array you pass as c doesn't need to have any particular order or type, i.e. it doesn't need to be sorted or integers as in these examples. The plotting routine will scale the colormap such that the minimum/maximum values in c correspond to the bottom/top of the colormap.

Colormaps

You can change the colormap by adding

import matplotlib.cm as cm
plt.scatter(x, y, c=t, cmap=cm.cmap_name)

Importing matplotlib.cm is optional as you can call colormaps as cmap="cmap_name" just as well. There is a reference page of colormaps showing what each looks like. Also know that you can reverse a colormap by simply calling it as cmap_name_r. So either

plt.scatter(x, y, c=t, cmap=cm.cmap_name_r)
# or
plt.scatter(x, y, c=t, cmap="cmap_name_r")

will work. Examples are "jet_r" or cm.plasma_r. Here's an example with the new 1.5 colormap viridis:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(100)
y = x
t = x
fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.scatter(x, y, c=t, cmap='viridis')
ax2.scatter(x, y, c=t, cmap='viridis_r')
plt.show()

Sample Image

Colorbars

You can add a colorbar by using

plt.scatter(x, y, c=t, cmap='viridis')
plt.colorbar()
plt.show()

Sample Image

Note that if you are using figures and subplots explicitly (e.g. fig, ax = plt.subplots() or ax = fig.add_subplot(111)), adding a colorbar can be a bit more involved. Good examples can be found here for a single subplot colorbar and here for 2 subplots 1 colorbar.

Matplotlib: common color map for 2 scatter plots within the same plot

I guess you can just use the flat version of the array:

import matplotlib.pyplot as plt
import numpy as np

# Bivariate time-series of length 10
nchannel, length = 2, 10
array_series = np.random.random((nchannel, length))
array_colors = np.random.random((nchannel, length))

x = np.arange(length)

plt.plot(x, array_series[0,:])
plt.plot(x, array_series[1,:])

xs = np.tile(x, nchannel)
plt.scatter(xs, array_series.flat, c=array_colors.flat)

plt.show()

Coloring based on specific conditions for Scatter Plot in Python

Created a categorical color column based on the condition & applied color

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

city = ["abc","def","ghi","jkl","mno","pqr","stu","vwx", "yza", "bcd"]
eu = ["no","no","no","no","no","no","no","no","no","no"]
coast = ["no","no","no","no","no","no","no","no","no","no"]
lat = [42.50,52.61,52.10,42,47.76,44.82,44.82,6.68,6.43,8.40]
temp = [7.50,5.61,4.10,8,9.76,10.82,3.82,4.68,1.43,5.40]

df1 = pd.DataFrame({'city':city, 'eu':eu, 'coast':coast, 'latitude':lat, 'temprature':temp})

df1.loc[df1['temprature'] > 10, 'color'] = 'R'
df1.loc[((df1['temprature'] > 6) & (df1['temprature'] <= 10)), 'color'] = 'O'
df1.loc[df1['temprature'] < 6, 'color'] = 'B'

fig, ax = plt.subplots(figsize=(6, 6))
colors = {'R':'tab:red', 'O':'tab:orange', 'B':'tab:blue'}
ax.scatter(df1['temprature'], df1['latitude'], c=df1['color'].map(colors))

handles = [Line2D([0], [0], marker='o', color='w', markerfacecolor=v, label=k, markersize=8) for k, v in colors.items()]
ax.legend(title='color', handles=handles, bbox_to_anchor=(1.05, 1), loc='upper left')

plt.show()

Scatter points with colormap for increasing indices

Look at this one

x = range(20)
plt.scatter(x, x, c=x, cmap=plt.get_cmap('Blues'))

It seems you can just pass the indices to c argument

Plotting a scatter plot from individual points, how to color points from a colormap?

Use the ax.scatter for each point as you're doing in your second block, but combine with a newly created newcmp including the arguments vmin and vmax to map the color array c to the colormap cmap.

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from matplotlib.colors import ListedColormap

markers = np.array(["1","2","3","4","+",">"])

# Dummy Data
x = np.array([0, 2, 3, 4, 0, 1, 5, 6, 7, 8])
y = np.array([0, 1, 0, 2, 3, 4, 5, 6, 7, 8])
c = np.array([0, 0.4, 0, 0.2, 1, 0.8, 0.9, 1, 1, 1])
m = np.array([0, 0, 0, 1, 1, 2, 3, 4, 5, 3])

# Figure
fig, ax = plt.subplots(figsize=(8,7))

hsv_modified = cm.get_cmap('hsv', 500)
newcmp = ListedColormap(hsv_modified(np.linspace(0.0, 0.3, 500)))

for xi,yi,mi,ci in zip(x,y,m,c):
ax.scatter(xi,yi,c=ci, marker=markers[mi], s=200, cmap=newcmp, vmin=min(c), vmax=max(c))

plt.show()

scatter_different_markers

Create scatter plot where the color is based on year without adding extra column

A 'cheap' way to color your scatter dots according to the year is to directly use matplotlib's scatter plot and pass the year as argument for the c parameter of scatter.

Here is a minimal example:

import datetime
import pandas as pd
from matplotlib import pyplot as plt
mydf = pd.DataFrame((
(datetime.datetime(2020, 1, 1, 23, 00), 0.08, 0.3),
(datetime.datetime(2021, 2,2,1,2,55), 0.2, 0.12),
(datetime.datetime(2022, 2,3,11, 00), 0.12, 0.7)
),
columns=("TIME", 'X', 'Y')
)

plt.scatter(mydf.X, mydf.Y, c=mydf.TIME.dt.year)

plt.show()

Sample Image
Then you can use the cmap parameter to specify what colormap you want to apply.

Setting different color for each series in scatter plot on matplotlib

I don't know what you mean by 'manually'. You can choose a colourmap and make a colour array easily enough:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]

colors = cm.rainbow(np.linspace(0, 1, len(ys)))
for y, c in zip(ys, colors):
plt.scatter(x, y, color=c)

Matplotlib graph with different colors

Or you can make your own colour cycler using itertools.cycle and specifying the colours you want to loop over, using next to get the one you want. For example, with 3 colours:

import itertools

colors = itertools.cycle(["r", "b", "g"])
for y in ys:
plt.scatter(x, y, color=next(colors))

Matplotlib graph with only 3 colors

Come to think of it, maybe it's cleaner not to use zip with the first one neither:

colors = iter(cm.rainbow(np.linspace(0, 1, len(ys))))
for y in ys:
plt.scatter(x, y, color=next(colors))


Related Topics



Leave a reply



Submit