Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Ok, I've made a somewhat satisfactory solution. It is wordy and still a bit hackish, but it works! It provides a <strong>fixed display offset</strong> around each point, it stands against interactive stuff - zooming, panning etc - and maintains the same display offset whatever you do.</p> <p>It works by creating a custom <code>matplotlib.transforms.Transform</code> object for each line patch in a plot. It is certainly a slow solution, but plots of this kind are not intended to be used with hundreds or thousands of points, so I guess performance is not such a big deal.</p> <p>Ideally, all those patches are needed to be combined into one single "plot-line", but it suits me as it is.</p> <pre><code>import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt class MyTransform(mpl.transforms.Transform): input_dims = 2 output_dims = 2 def __init__(self, base_point, base_transform, offset, *kargs, **kwargs): self.base_point = base_point self.base_transform = base_transform self.offset = offset super(mpl.transforms.Transform, self).__init__(*kargs, **kwargs) def transform_non_affine(self, values): new_base_point = self.base_transform.transform(self.base_point) t = mpl.transforms.Affine2D().translate(-new_base_point[0], -new_base_point[1]) values = t.transform(values) x = values[:, 0:1] y = values[:, 1:2] r = np.sqrt(x**2+y**2) new_r = r-self.offset new_r[new_r&lt;0] = 0.0 new_x = new_r/r*x new_y = new_r/r*y return t.inverted().transform(np.concatenate((new_x, new_y), axis=1)) def my_plot(X,Y): ax = plt.gca() line, = ax.plot(X, Y, marker='o', linestyle='') color = line.get_color() size = X.size for i in range(1,size): mid_x = (X[i]+X[i-1])/2 mid_y = (Y[i]+Y[i-1])/2 # this transform takes data coords and returns display coords t = ax.transData # this transform takes display coords and # returns them shifted by `offset' towards `base_point' my_t = MyTransform(base_point=(mid_x, mid_y), base_transform=t, offset=10) # resulting combination of transforms t_end = t + my_t line, = ax.plot( [X[i-1], X[i]], [Y[i-1], Y[i]], linestyle='-', color=color) line.set_transform(t_end) fig = plt.figure(figsize=(8,6)) axes = plt.subplot(111) X = np.linspace(0,2*np.pi, 8) Y = np.sin(X) my_plot(X,Y) plt.show() </code></pre> <p><img src="https://i.stack.imgur.com/9jphL.png" alt="enter image description here"></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload