How to draw lines between mouseclicks on a matplotlib plot?
Question:
This answer shows an excellent way of getting coordinates of mouse clicks on a matplotlib plot using mpl_point_clicker.
With a few clicks and this code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_point_clicker import clicker
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(np.sin(np.arange(200)/(5*np.pi)))
klicker = clicker(ax, ["event"], markers=["x"])
plt.show()
print(klicker.get_positions())
I am able to produce this plot:
and this textual output:
{'event': array([[ 5.83720666e+00, -5.73988654e-01],
[ 2.46956149e+01, -1.41575199e-02],
[ 5.20403030e+01, 5.70227612e-01],
[ 8.55139728e+01, 7.56837990e-01],
[ 1.30302686e+02, 3.73795635e-01],
[ 1.69433877e+02, -2.40054293e-01],
[ 2.01493167e+02, -5.05237462e-01]])}
which I can use to produce this plot:
with this code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_point_clicker import clicker
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(np.sin(np.arange(200)/(5*np.pi)))
klicker = clicker(ax, ["event"], markers=["x"])
data =
np.array([[ 5.83720666e+00, -5.73988654e-01],
[ 2.46956149e+01, -1.41575199e-02],
[ 5.20403030e+01, 5.70227612e-01],
[ 8.55139728e+01, 7.56837990e-01],
[ 1.30302686e+02, 3.73795635e-01],
[ 1.69433877e+02, -2.40054293e-01],
[ 2.01493167e+02, -5.05237462e-01]])
plt.plot(data[:,0],data[:,1],c='r')
plt.show()
print(klicker.get_positions())
However, I would like to draw this line as I am clicking on the plot. Ie instead of points drawn when I click on the graph on the first plot, I would like to have a line drawn between the points I click. I’d like the end result look similar to my second plot, but without needing a second script to create that plot. If I click at some new place on the plot, the red line should extend to this new location. As text output, I would like to have the coordinates of my clicks, just like in the examples above.
How can I achieve this in Python?
Answers:
The API says:
**line_kwargs (kwargs) – Line2D objects (from ax.plot) are used to generate the markers. line_kwargs will be passed through to all of the ax.plot calls.
So, let’s set the linestyle:
klicker = clicker(ax, ["event"], markers=["x"], **{"linestyle": "--"})
Other Line2D keywords can be found here.
I tried running your script but this time I put it inside class and method, and it seems it cannot work. Do you have any opinion about this?
import numpy as np
import matplotlib.pyplot as plt
from mpl_point_clicker import clicker
class model():
def __init__(self,name):
self.name = name
fig, ax = plt.subplots()
ax.plot(np.sin(np.arange(200)/(5*np.pi)))
klicker = clicker(ax, [self.name], markers=["x"])
plt.show()
self.coordinate = klicker.get_positions()[self.name]
def proccess(self):
print(self.coordinate)
A = model("event")
A.proccess()
and this will only result on showing the plot, but I cannot produce the marker when I clicked the plot, let alone reading the coordinates. Please kindly help?
This answer shows an excellent way of getting coordinates of mouse clicks on a matplotlib plot using mpl_point_clicker.
With a few clicks and this code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_point_clicker import clicker
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(np.sin(np.arange(200)/(5*np.pi)))
klicker = clicker(ax, ["event"], markers=["x"])
plt.show()
print(klicker.get_positions())
I am able to produce this plot:
and this textual output:
{'event': array([[ 5.83720666e+00, -5.73988654e-01],
[ 2.46956149e+01, -1.41575199e-02],
[ 5.20403030e+01, 5.70227612e-01],
[ 8.55139728e+01, 7.56837990e-01],
[ 1.30302686e+02, 3.73795635e-01],
[ 1.69433877e+02, -2.40054293e-01],
[ 2.01493167e+02, -5.05237462e-01]])}
which I can use to produce this plot:
with this code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_point_clicker import clicker
fig, ax = plt.subplots(constrained_layout=True)
ax.plot(np.sin(np.arange(200)/(5*np.pi)))
klicker = clicker(ax, ["event"], markers=["x"])
data =
np.array([[ 5.83720666e+00, -5.73988654e-01],
[ 2.46956149e+01, -1.41575199e-02],
[ 5.20403030e+01, 5.70227612e-01],
[ 8.55139728e+01, 7.56837990e-01],
[ 1.30302686e+02, 3.73795635e-01],
[ 1.69433877e+02, -2.40054293e-01],
[ 2.01493167e+02, -5.05237462e-01]])
plt.plot(data[:,0],data[:,1],c='r')
plt.show()
print(klicker.get_positions())
However, I would like to draw this line as I am clicking on the plot. Ie instead of points drawn when I click on the graph on the first plot, I would like to have a line drawn between the points I click. I’d like the end result look similar to my second plot, but without needing a second script to create that plot. If I click at some new place on the plot, the red line should extend to this new location. As text output, I would like to have the coordinates of my clicks, just like in the examples above.
How can I achieve this in Python?
The API says:
**line_kwargs (kwargs) – Line2D objects (from ax.plot) are used to generate the markers. line_kwargs will be passed through to all of the ax.plot calls.
So, let’s set the linestyle:
klicker = clicker(ax, ["event"], markers=["x"], **{"linestyle": "--"})
Other Line2D keywords can be found here.
I tried running your script but this time I put it inside class and method, and it seems it cannot work. Do you have any opinion about this?
import numpy as np
import matplotlib.pyplot as plt
from mpl_point_clicker import clicker
class model():
def __init__(self,name):
self.name = name
fig, ax = plt.subplots()
ax.plot(np.sin(np.arange(200)/(5*np.pi)))
klicker = clicker(ax, [self.name], markers=["x"])
plt.show()
self.coordinate = klicker.get_positions()[self.name]
def proccess(self):
print(self.coordinate)
A = model("event")
A.proccess()
and this will only result on showing the plot, but I cannot produce the marker when I clicked the plot, let alone reading the coordinates. Please kindly help?