19

How to add points to the existing diagram? The straightforward solution is to plot a new scatter, adding new data.

ax.scatter(data[:,0], data[:,1], cmap = cmap, c = color_data)
ax.scatter(new_points_x, new_points_y, color='blue')

But if we want to add more points with new colors, there is a problem: we have to take into consideration all previously added points.

It would be great if I could use a special function like

AddPoint(ax, new_point, color)

I want only add new points in new colors. I do NOT need any animations

toyewonug
  • 211
  • 1
  • 2
  • 5
  • 2
    Possible duplicate of [Dynamically updating plot in matplotlib](https://stackoverflow.com/questions/10944621/dynamically-updating-plot-in-matplotlib) – DatHydroGuy Dec 05 '18 at 10:33
  • @DatHydroGuy yes, I seen it before, but I do not need any animations and so on. I just need to add some new data with new color – toyewonug Dec 05 '18 at 10:36
  • So the first scatter has a colormap, and the points you want to add shall have a color that is not part of the original colormap? – ImportanceOfBeingErnest Dec 05 '18 at 10:56
  • @ImportanceOfBeingErnest exactly. And I already have a plot. How to add points on it? – toyewonug Dec 05 '18 at 11:35

3 Answers3

14

To just add a new data with new colour, indeed calling again scatter will add the new points with the specified colour:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
a = np.random.rand(10)
plt.scatter(x, a, c='blue')
b = np.random.rand(10)
plt.scatter(x, b, c='red')
plt.show()

enter image description here

b-fg
  • 3,959
  • 2
  • 28
  • 44
  • It seems to me that the code is what I showed just having different variable names – toyewonug Dec 05 '18 at 10:53
  • Yes, but I posted it so it was showed that you can call it multiple time and they actually add on top of each other. not sure what your problem is then. Please edit your question to make it clearer. – b-fg Dec 05 '18 at 10:59
  • 2
    I have an **exisiting** plot and want to add a new point on it – toyewonug Dec 05 '18 at 11:34
  • Still unclear, as I have an existing plot in my code and I add new points to it. Show your whole code or a minimal working example and your expected output. – b-fg Dec 05 '18 at 11:37
  • please, look at the second part of the question >>It would be great if I could use a special function like `AddPoint` – toyewonug Dec 05 '18 at 11:39
  • 2
    @b-fg There are many reasons why you might want new points attached to an existing curve, instead of one new scatter per new point. Your solution works *visually* but then you cannot do anything later like retrieving the data, adding two curves together, changing a transparency... Those things are easy if one y(x) curve has a unique `gid` and contains all of its data. If you have multiple scatters it becomes unnecessarily tough. – Guimoute Dec 19 '18 at 16:15
8

It's unclear why creating a second scatter, as suggested by @b-fg, is not acceptable, but you could write a function like so:

def addPoint(scat, new_point, c='k'):
    old_off = scat.get_offsets()
    new_off = np.concatenate([old_off,np.array(new_point, ndmin=2)])
    old_c = scat.get_facecolors()
    new_c = np.concatenate([old_c, np.array(matplotlib.colors.to_rgba(c), ndmin=2)])

    scat.set_offsets(new_off)
    scat.set_facecolors(new_c)

    scat.axes.figure.canvas.draw_idle()

which allows you to add a new point to an existing PathCollection.

example:

fig, ax = plt.subplots()
scat = ax.scatter([0,1,2],[3,4,5],cmap=matplotlib.cm.spring, c=[0,2,1])
fig.canvas.draw()  # if running all the code in the same cell, this is required for it to work, not sure why
addPoint(scat, [3,6], 'c')
addPoint(scat, [3.1,6.1], 'pink')
addPoint(scat, [3.2,6.2], 'r')
addPoint(scat, [3.3,6.3], 'xkcd:teal')
ax.set_xlim(-1,4)
ax.set_ylim(2,7)

enter image description here

Note that the function that I'm proposing is very basic and would need to be made much smarter depending on the use case. It is important to realize that the facecolors array in a PathCollection does not necessarily have the same number of elements as the number of points, so funny things can happen with colors if you try to add several points as once, or if the original points are all the same colors, etc...

Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
  • 1
    *"Why do I need to `draw` the canvas for this to work"* - because only then the facecolors are actually applied from the colormap and norm. You may replace that line by `scat.update_scalarmappable()` in order not to draw everything. However, as you point out, there are many cases where this approach fails, so one should be careful to rely on any plot that's produced this way. – ImportanceOfBeingErnest Dec 05 '18 at 12:00
  • 1
    Just to add a silly point...? My God... I thought Python was do anything in one line of code or less..? Wow... I could almost do that in C.... whew.... –  Jul 01 '19 at 10:49
2

Assuming you already have a plot, you can create this function.

def AddPoint(plot, x, y, color):
    plot.scatter(x, y, c=color)
    plot.clf()
    plot.show()