Search code examples
pythonpandasmatplotlib

Calculate the volume of 3d plot python


A simple code that builds a 3D graph based on the coordinates of points:

import pandas as pd
import matplotlib.pyplot as plt

with open('data\\PS.txt', 'r') as f:
    df = pd.read_csv(f, sep=",")
    
x = df['x'].values.tolist()
y = df['y'].values.tolist()
z = df['z'].values.tolist()

fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(x, y, z)

plt.show()  

Here is the 3D figure itself: enter image description here

Now it is necessary to calculate the volume of this figure. How do I calculate the volume of a figure?

File contents "PS.txt" it looks like this:

1,152691.129,213258.428,631.716 2,152691.316,213256.857,631.827 3,152692.729,213255.315,631.945 4,152695.035,213250.459,631.882 5,152696.787,213246.130,632.107 6,152698.298,213242.364,631.578 7,152699.839,213239.028,631.723 8,152700.217,213237.356,631.350 9,152701.883,213233.297,631.206 10,152702.981,213229.478,631.392 11,152705.247,213224.878,631.609 12,152706.485,213222.668,632.294 13,152708.542,213219.988,632.765 14,152708.552,213220.002,632.750 15,152711.060,213215.836,632.809 16,152713.617,213211.422,632.346 17,152718.564,213202.802,631.409 18,152722.731,213197.100,631.362 19,152726.272,213192.046,631.498 20,152730.236,213186.253,631.371 21,152734.179,213180.031,631.452 22,152737.690,213175.369,631.344 23,152741.310,213177.118,631.309 24,152748.978,213182.575,631.163 25,152756.270,213188.301,631.247 26,152759.305,213190.724,631.267 27,152762.942,213192.492,631.256 28,152765.987,213194.916,631.162 29,152769.216,213197.108,631.358 30,152771.065,213200.136,631.245 31,152769.791,213202.537,631.736 32,152767.962,213205.946,631.614 33,152764.967,213211.123,631.717 34,152762.501,213215.213,631.571 35,152758.903,213221.344,631.816 36,152757.514,213225.138,632.015 37,152754.682,213229.676,631.975 38,152751.918,213234.024,631.889 39,152748.804,213239.425,632.106 40,152745.263,213245.349,631.928 41,152741.336,213251.451,631.912 42,152737.827,213256.240,632.071 43,152733.422,213263.828,632.060 44,152729.597,213269.791,632.211 45,152727.207,213273.974,632.440 46,152725.795,213276.797,632.435 47,152725.042,213277.064,632.554 48,152723.422,213276.584,632.513 49,152715.066,213272.147,632.442 50,152709.221,213268.936,632.387 51,152702.480,213264.648,632.467 52,152697.043,213261.739,632.231 53,152693.678,213259.727,632.141 54,152718.231,213206.304,629.044 55,152720.573,213203.068,628.925 56,152723.331,213199.193,628.898 57,152723.927,213196.993,628.870 58,152728.193,213190.552,628.813 59,152731.767,213185.322,628.960 60,152735.617,213179.673,629.032 61,152737.550,213176.409,629.168 62,152740.349,213177.727,629.093 63,152747.789,213183.248,628.736 64,152755.001,213188.781,628.874 65,152758.970,213192.543,629.045 66,152761.357,213193.329,629.181 67,152766.041,213196.920,629.269 68,152767.944,213199.372,629.367 69,152768.401,213201.151,629.219 70,152764.862,213207.360,629.122 71,152761.754,213212.748,629.312 72,152757.478,213220.474,629.310 73,152753.623,213228.269,629.393 74,152748.167,213237.432,629.557 75,152742.455,213247.561,629.629 76,152737.519,213254.209,629.883 77,152733.522,213259.618,630.021 78,152732.286,213261.395,629.511 79,152728.106,213268.732,629.516 80,152726.549,213271.128,629.326 81,152723.805,213274.373,629.317 82,152721.984,213273.677,629.192 83,152716.138,213270.812,629.574 84,152710.821,213268.060,629.567 85,152706.132,213265.473,629.309 86,152701.330,213262.217,628.895 87,152697.388,213260.418,628.983 88,152694.490,213258.500,629.225 89,152693.393,213258.304,629.621 90,152694.345,213256.439,629.329 91,152696.949,213251.571,629.259 92,152698.927,213246.215,629.155 93,152700.346,213242.499,629.009 94,152702.244,213238.054,628.970 95,152703.983,213233.276,628.897 96,152705.018,213229.281,629.012 97,152706.526,213226.382,629.127 98,152707.929,213223.484,629.261 99,152711.127,213219.338,629.268 100,152713.425,213215.829,629.093 101,152716.183,213210.623,628.744 102,152699.816,213255.436,628.810 103,152703.999,213257.574,628.649 104,152708.446,213259.993,629.049 105,152715.256,213263.596,629.281 106,152719.561,213265.977,629.373 107,152724.048,213268.319,629.370 108,152726.984,213263.115,629.579 109,152724.089,213260.586,629.322 110,152718.138,213256.749,629.407 111,152713.111,213253.939,629.257 112,152709.817,213251.502,628.953 113,152707.199,213249.989,628.670 114,152702.574,213247.411,628.844 115,152705.577,213241.685,628.898 116,152710.906,213244.101,628.792 117,152715.875,213246.241,628.887 118,152717.636,213247.094,629.211 119,152725.472,213251.103,629.307 120,152728.123,213252.443,629.553 121,152731.916,213254.534,629.897 122,152736.446,213247.816,629.464 123,152732.745,213245.056,629.233 124,152727.080,213241.423,629.124 125,152721.365,213238.400,628.874 126,152714.975,213234.559,628.970 127,152708.530,213231.420,628.871 128,152712.677,213225.120,629.003 129,152716.666,213227.440,628.856 130,152722.213,213230.296,628.799 131,152726.407,213232.656,628.672 132,152731.916,213235.770,628.876 133,152736.523,213238.443,629.147 134,152740.674,213240.783,629.344 135,152744.868,213234.142,629.359 136,152740.977,213231.527,629.126 137,152735.601,213228.189,628.759 138,152730.823,213225.042,628.534 139,152726.882,213222.278,628.481 140,152722.476,213218.921,628.594 141,152718.191,213215.736,628.733 142,152722.108,213210.698,628.572 143,152727.304,213212.925,628.314 144,152732.755,213215.602,628.129 145,152738.899,213219.785,628.257 146,152741.104,213221.031,628.425 147,152745.450,213223.517,628.798 148,152749.876,213225.960,629.039 149,152753.427,213219.757,629.075 150,152748.345,213216.114,628.684 151,152743.630,213212.799,628.256 152,152737.131,213209.291,628.304 153,152730.671,213206.158,628.415 154,152726.464,213203.380,628.630 155,152729.335,213198.258,628.759 156,152733.621,213200.345,628.489 157,152738.154,213202.717,628.415 158,152744.284,213206.303,628.709 159,152748.297,213209.516,628.499 160,152752.498,213212.363,628.883 161,152754.904,213213.741,629.372 162,152757.685,213211.582,629.352 163,152758.353,213208.933,629.254 164,152760.346,213209.123,629.314 165,152760.941,213206.380,629.142 166,152760.128,213202.271,629.014 167,152757.335,213198.594,628.844 168,152755.759,213197.339,628.822 169,152763.289,213200.301,629.009 170,152759.572,213197.326,628.975 171,152756.591,213199.072,628.574 172,152759.201,213202.392,628.390 173,152759.462,213204.784,628.457 174,152756.864,213206.414,628.606 175,152757.359,213208.721,628.897 176,152756.466,213210.988,629.069 177,152751.499,213204.059,628.700 178,152746.819,213201.102,628.749 179,152741.889,213198.339,628.611 180,152739.042,213196.746,628.669 181,152735.780,213194.626,628.932 182,152731.677,213192.081,628.950 183,152735.933,213187.082,628.857 184,152740.588,213190.671,628.946 185,152745.251,213194.414,628.803 186,152749.876,213197.718,628.695 187,152753.870,213200.839,628.717 188,152754.703,213194.185,628.870 189,152748.420,213189.568,628.785 190,152740.765,213183.848,628.788

Thank you all.


Solution

  • The first trick was reading your text file into a dataframe with x, y, and z columns (not a necessary step for finding volume). Since it's not a csv or a regularly delimited file, it doesn't read easily with pd.read_csv(). You could either clean up the raw file first to make it more easily readable or clean it up after reading it in. I chose the latter.

    import numpy as np, pandas as pd
    from scipy.spatial import ConvexHull
    
    df = pd.read_csv('PS.txt', sep=' ', header=None).stack().str.split(',', expand=True)
    df = pd.concat([df[[1,2,3]].rename(columns={1:'x', 2:'y', 3:'z'}),
                    df[[4,5,6]].dropna().rename(columns={4:'x', 5:'y', 6:'z'})], ignore_index=True)
    
    >>> df
                 x           y        z
    0   152691.129  213258.428  631.716
    1   152691.316  213256.857  631.827
    2   152692.729  213255.315  631.945
    3   152695.035  213250.459  631.882
    4   152696.787  213246.130  632.107
    ... ... ... ...
    375 152753.870  213200.839  628.717
    376 152754.703  213194.185  628.870
    377 152748.420  213189.568  628.785
    378 152740.765  213183.848  628.788
    379 152691.129  213258.428  631.716
    380 rows × 3 columns
    

    For finding the volume of convex polyhedrons you can use scipy.spatial.ConvexHull.

    volume = ConvexHull(df.values).volume
    
    >>> volume
    13977.540571063422
    

    Alternatively, you could just extract the points to find the volume without using a dataframe.

    raw_string = '1,152691.129,213258.428,631.716 2,152691.316,213256.857,631.827 3,152692.729,213255.315,631.945 4,152695.035,213250.459,631.882 5,152696.787,213246.130,632.107 6,152698.298,213242.364,631.578 7,152699.839,213239.028,631.723 8,152700.217,213237.356,631.350 9,152701.883,213233.297,631.206 10,152702.981,213229.478,631.392 11,152705.247,213224.878,631.609 12,152706.485,213222.668,632.294 13,152708.542,213219.988,632.765 14,152708.552,213220.002,632.750 15,152711.060,213215.836,632.809 16,152713.617,213211.422,632.346 17,152718.564,213202.802,631.409 18,152722.731,213197.100,631.362 19,152726.272,213192.046,631.498 20,152730.236,213186.253,631.371 21,152734.179,213180.031,631.452 22,152737.690,213175.369,631.344 23,152741.310,213177.118,631.309 24,152748.978,213182.575,631.163 25,152756.270,213188.301,631.247 26,152759.305,213190.724,631.267 27,152762.942,213192.492,631.256 28,152765.987,213194.916,631.162 29,152769.216,213197.108,631.358 30,152771.065,213200.136,631.245 31,152769.791,213202.537,631.736 32,152767.962,213205.946,631.614 33,152764.967,213211.123,631.717 34,152762.501,213215.213,631.571 35,152758.903,213221.344,631.816 36,152757.514,213225.138,632.015 37,152754.682,213229.676,631.975 38,152751.918,213234.024,631.889 39,152748.804,213239.425,632.106 40,152745.263,213245.349,631.928 41,152741.336,213251.451,631.912 42,152737.827,213256.240,632.071 43,152733.422,213263.828,632.060 44,152729.597,213269.791,632.211 45,152727.207,213273.974,632.440 46,152725.795,213276.797,632.435 47,152725.042,213277.064,632.554 48,152723.422,213276.584,632.513 49,152715.066,213272.147,632.442 50,152709.221,213268.936,632.387 51,152702.480,213264.648,632.467 52,152697.043,213261.739,632.231 53,152693.678,213259.727,632.141 54,152718.231,213206.304,629.044 55,152720.573,213203.068,628.925 56,152723.331,213199.193,628.898 57,152723.927,213196.993,628.870 58,152728.193,213190.552,628.813 59,152731.767,213185.322,628.960 60,152735.617,213179.673,629.032 61,152737.550,213176.409,629.168 62,152740.349,213177.727,629.093 63,152747.789,213183.248,628.736 64,152755.001,213188.781,628.874 65,152758.970,213192.543,629.045 66,152761.357,213193.329,629.181 67,152766.041,213196.920,629.269 68,152767.944,213199.372,629.367 69,152768.401,213201.151,629.219 70,152764.862,213207.360,629.122 71,152761.754,213212.748,629.312 72,152757.478,213220.474,629.310 73,152753.623,213228.269,629.393 74,152748.167,213237.432,629.557 75,152742.455,213247.561,629.629 76,152737.519,213254.209,629.883 77,152733.522,213259.618,630.021 78,152732.286,213261.395,629.511 79,152728.106,213268.732,629.516 80,152726.549,213271.128,629.326 81,152723.805,213274.373,629.317 82,152721.984,213273.677,629.192 83,152716.138,213270.812,629.574 84,152710.821,213268.060,629.567 85,152706.132,213265.473,629.309 86,152701.330,213262.217,628.895 87,152697.388,213260.418,628.983 88,152694.490,213258.500,629.225 89,152693.393,213258.304,629.621 90,152694.345,213256.439,629.329 91,152696.949,213251.571,629.259 92,152698.927,213246.215,629.155 93,152700.346,213242.499,629.009 94,152702.244,213238.054,628.970 95,152703.983,213233.276,628.897 96,152705.018,213229.281,629.012 97,152706.526,213226.382,629.127 98,152707.929,213223.484,629.261 99,152711.127,213219.338,629.268 100,152713.425,213215.829,629.093 101,152716.183,213210.623,628.744 102,152699.816,213255.436,628.810 103,152703.999,213257.574,628.649 104,152708.446,213259.993,629.049 105,152715.256,213263.596,629.281 106,152719.561,213265.977,629.373 107,152724.048,213268.319,629.370 108,152726.984,213263.115,629.579 109,152724.089,213260.586,629.322 110,152718.138,213256.749,629.407 111,152713.111,213253.939,629.257 112,152709.817,213251.502,628.953 113,152707.199,213249.989,628.670 114,152702.574,213247.411,628.844 115,152705.577,213241.685,628.898 116,152710.906,213244.101,628.792 117,152715.875,213246.241,628.887 118,152717.636,213247.094,629.211 119,152725.472,213251.103,629.307 120,152728.123,213252.443,629.553 121,152731.916,213254.534,629.897 122,152736.446,213247.816,629.464 123,152732.745,213245.056,629.233 124,152727.080,213241.423,629.124 125,152721.365,213238.400,628.874 126,152714.975,213234.559,628.970 127,152708.530,213231.420,628.871 128,152712.677,213225.120,629.003 129,152716.666,213227.440,628.856 130,152722.213,213230.296,628.799 131,152726.407,213232.656,628.672 132,152731.916,213235.770,628.876 133,152736.523,213238.443,629.147 134,152740.674,213240.783,629.344 135,152744.868,213234.142,629.359 136,152740.977,213231.527,629.126 137,152735.601,213228.189,628.759 138,152730.823,213225.042,628.534 139,152726.882,213222.278,628.481 140,152722.476,213218.921,628.594 141,152718.191,213215.736,628.733 142,152722.108,213210.698,628.572 143,152727.304,213212.925,628.314 144,152732.755,213215.602,628.129 145,152738.899,213219.785,628.257 146,152741.104,213221.031,628.425 147,152745.450,213223.517,628.798 148,152749.876,213225.960,629.039 149,152753.427,213219.757,629.075 150,152748.345,213216.114,628.684 151,152743.630,213212.799,628.256 152,152737.131,213209.291,628.304 153,152730.671,213206.158,628.415 154,152726.464,213203.380,628.630 155,152729.335,213198.258,628.759 156,152733.621,213200.345,628.489 157,152738.154,213202.717,628.415 158,152744.284,213206.303,628.709 159,152748.297,213209.516,628.499 160,152752.498,213212.363,628.883 161,152754.904,213213.741,629.372 162,152757.685,213211.582,629.352 163,152758.353,213208.933,629.254 164,152760.346,213209.123,629.314 165,152760.941,213206.380,629.142 166,152760.128,213202.271,629.014 167,152757.335,213198.594,628.844 168,152755.759,213197.339,628.822 169,152763.289,213200.301,629.009 170,152759.572,213197.326,628.975 171,152756.591,213199.072,628.574 172,152759.201,213202.392,628.390 173,152759.462,213204.784,628.457 174,152756.864,213206.414,628.606 175,152757.359,213208.721,628.897 176,152756.466,213210.988,629.069 177,152751.499,213204.059,628.700 178,152746.819,213201.102,628.749 179,152741.889,213198.339,628.611 180,152739.042,213196.746,628.669 181,152735.780,213194.626,628.932 182,152731.677,213192.081,628.950 183,152735.933,213187.082,628.857 184,152740.588,213190.671,628.946 185,152745.251,213194.414,628.803 186,152749.876,213197.718,628.695 187,152753.870,213200.839,628.717 188,152754.703,213194.185,628.870 189,152748.420,213189.568,628.785 190,152740.765,213183.848,628.788'
    points = []
    for x in raw_string.split(' '):
        current_line = [float(x) for x in x.split(',')[1:]]
        if len(current_string)%3==0:
            if len(current_line)!=3:
                for n in range(1, int((len(current_line)/3)+1)):
                    points.append(current_line[3*(n-1):3*n])
            else:
                points.append(current_line)
        else:
            continue
    volume = ConvexHull(points).volume
    
    >>> volume
    13977.540571063422