7

I have a numpy array X of timeserieses. Something like that:

[[0.05, -0.021, 0.003, 0.025, -0.001, -0.023, 0.095, 0.001, -0.018]
[0.015, 0.011, -0.032, -0.044, -0.002, 0.032, -0.051, -0.03, -0.020]
[0.04, 0.081, -0.02, 0.014, 0.063, -0.077, 0.059, 0.031, 0.025]]

I can plot this with

fig, axes = plt.subplots(3, 1)
for i in range(3):
    axes[i].plot(X[i])
plt.show()

Then something like the following appears (the plots do not show the demo values I wrote above but other values with similar structure). So each row in X is one timeseries. enter image description here

But I want to have a numpy array which describes each timeseries as a grayscale image (because I want to use it for a cnn later). So I think what I need should be something like that:

[[[0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 1]
[0, 0, 1, 0, 0, 0]]
[[0, 0, 1, 0, 0, 0]
[0, 0, 0, 1, 0, 0]
[0, 1, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0]]...]

How is it (if possible: efficiently) possible to convert each timeseries into a matrix, which describes the timeseries as an image. So each row in the old array (e.g. this:

[0.05, -0.021, 0.003, 0.025, -0.001, -0.023, 0.095, 0.001, -0.018])

should be converted to a 2D matrix (e.g. something like this:

[[0, 0, 0, 0, 0, 1] [0, 0, 0, 0, 1, 0] [0, 0, 0, 0, 0, 1] [0, 0, 1, 0, 0, 0]]

Alternative describtion: Every row in X describes one timeseries. For each row in X I need a 2D matrix describing the timeseries as an image (like the plot shown above)

"Solution": Seems there is no nice solution to do this. I used this workaround now:

fig = plt.figure()
fig.add_subplot(111)
fig.tight_layout(pad=0)
plt.axis('off')
plt.plot(X[0], linewidth=3)
fig.canvas.draw()
data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))

The data contains the 2D matrix now and could be plotted with plt.imshow(data) again with some loss of quality.

L3n95
  • 1,505
  • 3
  • 25
  • 49
  • How do you want to do that? A row cannot be plotted as an image without reshaping it. And you don't give any information on how to reshape the row. You need to give us more information. – JE_Muc May 25 '18 at 10:21
  • The row can be plotted. Using z = np.array([0.05, -0.022, 0.03,...]) plt.plot(z) I get a plot looking like a plot shown above. So matplotlib does this conversion in any way too. – L3n95 May 25 '18 at 10:29
  • You need understand what arrays look like and what the meaning of dimensions is. If you have a one-dimension array, for example or a row of a multi-dimensional array, this **CANNOT** be plotted as a 2D-image without reshaping it to 2D, since it is **one-dimensional**. To plot a 2D image, you need two pass **two dimensional** data. – JE_Muc May 25 '18 at 10:35
  • Yes and that is exactly what I want to have. The matrix describing the 2D-image. I could plot every single row, export it as png and import it again to have matrix describing the image. I hope there is an easier way. – L3n95 May 25 '18 at 10:42
  • What? There is **only a 1D-matrix** if you want to plot each row separately. You need to **reshape** the row if you **want to have a 2D-matrix**. There is **no way without reshaping**! But you **CANNOT just reshape**. You need to provide more information! The wanted shape is required! – JE_Muc May 25 '18 at 10:47
  • You need to think of a row of an array as if it is a thread. You can't make a single thread into a plane without transforming it. This transformation is called reshaping in numpy. But ye need to give information about the shape! – JE_Muc May 25 '18 at 10:49
  • Yes but I only pass the 1D-matrix to matplotlib too and it generates a 2D-matrix (image). It reshapes it for me in any way. – L3n95 May 25 '18 at 10:51
  • 1
    Matplotlib just plots your data using a `LineCollection` and displays this in 2D. If you want to have a matrix representing the points in the 2D image as a matrix, you need to define the same point spacing and axes properties for each timeseries. – JE_Muc May 25 '18 at 11:00
  • Okay seems there is no nice solution to do this. I have added the used workaround to my question. Thanks for your help. – L3n95 May 25 '18 at 11:08
  • I'm trying to do the same thing you've done. I've tried something similar to you. However, yours seems to be more interesting. If you have any update, share it with us! thanks – Marlon Teixeira Jul 22 '20 at 16:54

2 Answers2

4

Take a look at these kaggle challange. It think you also want to implement parts of this paper like they do.

Maybe you can also use the function that they adopted from another SO question:

#modified from https://stackoverflow.com/questions/33650371/recurrence-plot-in-python
def recurrence_plot(s, eps=None, steps=None):
    if eps==None: eps=0.1
    if steps==None: steps=10
    d = sk.metrics.pairwise.pairwise_distances(s)
    d = np.floor(d / eps)
    d[d > steps] = steps
    #Z = squareform(d)
    return d
Fabian
  • 3,139
  • 2
  • 23
  • 49
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/20704109) – Gerhard Aug 28 '18 at 08:32
  • @GerhardBarnard Thanks for the advice. I added the relevant code snipped – Fabian Aug 28 '18 at 08:47
0

You should write X differently:

import numpy as np
X = np.array([[0.05, -0.021, 0.003, 0.025, -0.001, -0.023, 0.095, 0.001, -0.018],
[0.015, 0.011, -0.032, -0.044, -0.002, 0.032, -0.051, -0.03, -0.020],
[0.04, 0.081, -0.02, 0.014, 0.063, -0.077, 0.059, 0.031, 0.025]])

It will give you the correct values. Then for the grayscale image:

plt.figure()
plt.imshow(X, cmap = 'gray')
  • No that is not what I need. Every row in X describes one timeseries and every row in X should be converted to a image. If we say the first row in X describes the first plotted image I want the matrix that lies behind the plot. So the matrix which describes the image. – L3n95 May 25 '18 at 10:01
  • @Robyn: I upvoted your answer, since this is imho the only way to plot the data with the information L3n95 provided. But it looks like L3n95 is not satisfied and downvoted it. – JE_Muc May 25 '18 at 10:36
  • Yes it seems we are talking about different things. With matplotlib I can plot every single row. So matplotlib needs to convert the 1D row into a 2D matrix. And I want to have this 2D matrix. The X I described above would result into several 2D matrixes and not in one big. – L3n95 May 25 '18 at 10:47