gudé
gudé

Reputation: 99

How to plot a 3D graph with Z axis being the magnitude of values in a csv?

I believe the X and Y values in the plot should be represented by the columns and lines in the csv, which looks like this:

0,original,1.0000,0.9999,0.9998,0.9997,0.9996,0.9995... 0.9900
1,28663,   4144,6096,6859,7366,7876,8125...
2,11268,   1374,2119,2393,2615,2809,2904...
3,14734,   2122,3115,3466,3740,4011,4144...
4,13341,   1452,2322,2689,2877,3114,3238...
5,18458,   2677,3643,4047,4333,4652,4806...
6,13732,   1621,2224,2502,2704,2930,3020...
7,17771,   2955,3904,4270,4566,4872,5041...
8,14447,   1822,2437,2715,2933,3179,3292...
.
.
.
5400,18458,2677,3643,4047,4333,4652,4806

I would like to plot my data in a graphic. If I do so in a 2D graphic it looks really ugly.

Image 1 shows this data in a 2D format, each column series is a different color, the "original" values are the blue series for example. It looks to me that it would have a better visual representation if it was 3D. enter image description here

I would be looking for something like image 2. I understand that the Z values are the magnitude of each cell in the table. I believe I would have to plot a bunch of different series (where each series comes from each whole column on the csv). Am I right?

enter image description here

That being said, my question is: How can I plot my '.csv' data in a 3D graphic, considering the situation I pointed out?

EDIT: I found a code that kinda does what I want. I got it from here. I guess I would like to apply each column like np.meshgrid(DataAll1D[:,0] adds column 0 to the plot. It seems like the meshgrid function accepts any number of 1D arrays I just don't know how to do that in python.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

DataAll1D = np.loadtxt("datacsv_1d.csv", delimiter=",")
# create 2d x,y grid (both X and Y will be 2d)
X, Y = np.meshgrid(DataAll1D[:,0], DataAll1D[:,1])

# repeat Z to make it a 2d grid
Z = np.tile(DataAll1D[:,2], (len(DataAll1D[:,2]), 1))

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, cmap='ocean')
plt.show()

Upvotes: 0

Views: 2580

Answers (1)

Patol75
Patol75

Reputation: 4547

A very minimal example, but I guess what you want to achieve is have each of your curves separated from the others in a 3D space. The code below generates two plots, one that draws curves individually, the other which treats the input as a surface. You can easily build onto this and achieve a more specific goal of yours I guess.

from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import
import matplotlib.pyplot as plt
import numpy

data = numpy.array([[28663, 4144, 6096, 6859, 7366, 7876, 8125],
                    [11268, 1374, 2119, 2393, 2615, 2809, 2904],
                    [14734, 2122, 3115, 3466, 3740, 4011, 4144],
                    [13341, 1452, 2322, 2689, 2877, 3114, 3238],
                    [18458, 2677, 3643, 4047, 4333, 4652, 4806],
                    [13732, 1621, 2224, 2502, 2704, 2930, 3020]])
fig, (ax, bx) = plt.subplots(nrows=1, ncols=2, num=0, figsize=(16, 8),
                             subplot_kw={'projection': '3d'})
for i in range(data.shape[1]):
    ax.plot3D(numpy.repeat(i, data.shape[0]), numpy.arange(data.shape[0]),
              data[:, i])
gridY, gridX = numpy.mgrid[1:data.shape[0]:data.shape[0] * 1j,
                           1:data.shape[1]:data.shape[1] * 1j]
pSurf = bx.plot_surface(gridX, gridY, data, cmap='viridis')
fig.colorbar(pSurf)
plt.show()

enter image description here

Upvotes: 2

Related Questions