omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    problem with 3d plot

    Pythonista
    3
    10
    4554
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jmv38
      jmv38 last edited by jmv38

      hello again
      I have another problem: in a simple scatter plot, the points are not plotted correctly in 3d. I use

      ax.scatter(x, y, z, s=80, color=c, marker='o', alpha=1.0, linewidth=0)
      

      I am working on Luv color space, and i try to visualize where the colors go. In the following graph, the brighter points should be above the darker ones, not behind.

      I have tried to plot the top group before or after or simultaneously but i always get the same image. Oh, and the top group is really above others...
      Note that the bottom black group is correctly plotted behind the pink one. So there doesnt seem to be any systematic rule for the plotting order?
      Any idea?
      Thanks.

      Matteo 1 Reply Last reply Reply Quote 0
      • jmv38
        jmv38 last edited by jmv38

        this is really weird: when i add more points this what i get now

        the order has changed but it seem random.
        The points are all stacked in 1d arrays x,y,z,c, starting from low L values to high L values.

        1 Reply Last reply Reply Quote 0
        • jmv38
          jmv38 last edited by

          by the way, can you see the images i have put in the post above? Not sure whether the links are permanent...

          cvp 1 Reply Last reply Reply Quote 0
          • cvp
            cvp @jmv38 last edited by

            @jmv38 we see them

            1 Reply Last reply Reply Quote 0
            • Matteo
              Matteo @jmv38 last edited by

              @jmv38 Hi in my opinion you should post here the full example that reproduces what you obtain with info about Pythonista version you use, in this way people that read your post can test your code quickly bye

              1 Reply Last reply Reply Quote 0
              • jmv38
                jmv38 last edited by jmv38

                @Matteo mmm when i try to select my whole code (only 300 lines) to copy it then Pythonista get frozen and i cant do anything but kill pythonista => is it a known bug?

                1 Reply Last reply Reply Quote 0
                • jmv38
                  jmv38 last edited by

                  here is the code

                  def rgb_to_XYZ(r, g, b):
                    ref = 0.17697
                    
                    r /= 255.0
                    g /= 255.0
                    b /= 255.0
                    
                    x = (r*0.49 + g*0.31   + b*0.2    ) / ref
                    y = (r*ref  + g*0.8124 + b*0.01063) / ref
                    z = (r*0.0  + g*0.01   + b*0.99   ) / ref
                    return x,y,z
                  
                  def XYZ_to_rgb(X, Y, Z):
                    r =  X * 0.41847     - Y * 0.15866   - Z * 0.082835
                    g = -X * 0.091169    + Y * 0.25243   + Z * 0.015708
                    b =  X * 0.00092090  - Y * 0.0025498 + Z * 0.17860
                    
                    r = int(r*255+0.5)
                    g = int(g*255+0.5)
                    b = int(b*255+0.5)
                    
                    return r,g,b
                  
                  # un utilitaire pour vérifier si le rgb est bien valide (pas tjrs le cas!)
                  def inside(mini,x,maxi):
                    return (mini<=x) and (x<=maxi)
                  def valid_rgb(r,g,b):
                    return inside(0,r,255) and inside(0,g,255) and inside(0,b,255)
                  
                  d = 6.0/29.0
                  d3 = d*d*d
                  d2 = d*d
                  y0 = 4.0/29.0
                  # un blanc de reference est necessaire pour les calculs CIE
                  r = 5.650675255693056/100 # necessaire pour convertir l'illuminant Y=100 dans le meme range que XYZ
                  D65 = (95.047*r,100.0*r,108.883*r)
                  Xn,Yn,Zn = D65
                  
                  def _forward(t):
                    if t > d3:
                      y = pow(t,1.0/3.0)
                    else:
                      y = t/3.0/d2 + y0
                    return y
                    
                  def _inverse(t):
                    if t > d:
                      y = t*t*t
                    else:
                      y = 3*d2*(t-y0)
                    return y
                  
                  # le systeme L*,u*,v* que j'appelle 'sLuv' comme 'star Luv'
                  # dans ce systeme, la distance euclidienne entre couleurs est a peu pres conforme à la JND de l'oeil
                  
                  Un = 4*Xn/(Xn+15*Yn+3*Zn)
                  Vn = 9*Yn/(Xn+15*Yn+3*Zn)
                  
                  def XYZ_to_sLuv(X, Y, Z):
                    L = 116*_forward(Y/Yn) - 16
                    s = (X+15*Y+3*Z)
                    if s==0 :
                      return 0.,0.,0.
                    Up = 4*X/s
                    Vp = 9*Y/s
                    u = 13*L*(Up-Un)
                    v = 13*L*(Vp-Vn)
                    L,u,v = round(L,3),round(u,3),round(v,3)
                    return L,u,v
                    
                  def rgb_to_sLuv(r,g,b):
                    X,Y,Z = rgb_to_XYZ(r,g,b)
                    return XYZ_to_sLuv(X, Y, Z)
                  
                  def sLuv_to_XYZ(L,u,v):
                    if L==0 :
                      return 0.,0.,0.
                    Y = Yn * _inverse((L+16)/116)
                    Up = u/13/L + Un
                    Vp = v/13/L + Vn
                    x = 9*Up/(6*Up-16*Vp+12)
                    y = 4*Vp/(6*Up-16*Vp+12)
                    X = x*Y/y
                    Z = (1-x-y)*Y/y
                    return X,Y,Z
                  
                  def sLuv_to_rgb(L,u,v):
                    X,Y,Z = sLuv_to_XYZ(L,u,v)
                    return XYZ_to_rgb(X, Y, Z)
                  
                  def get_sLuv_limits():
                    Lmin,Umin,Vmin = rgb_to_sLuv(0,0,0)
                    Lmax,Umax,Vmax = Lmin,Umin,Vmin
                    for r in [0,255]:
                      for g in [0,255]:
                        for b in [0,255]:
                          L,u,v = rgb_to_sLuv(r,g,b)
                          Lmin,Umin,Vmin = min(Lmin,L),min(Umin,u),min(Vmin,v)
                          Lmax,Umax,Vmax = max(Lmax,L),max(Umax,u),max(Vmax,v)
                    return Lmin,Umin,Vmin,Lmax,Umax,Vmax
                    
                  def get_limits(toLuv):
                    Lmin,Umin,Vmin = toLuv(0,0,0)
                    Lmax,Umax,Vmax = Lmin,Umin,Vmin
                    for r in [0,255]:
                      for g in [0,255]:
                        for b in [0,255]:
                          L,u,v = rgb_to_sLuv(r,g,b)
                          Lmin,Umin,Vmin = min(Lmin,L),min(Umin,u),min(Vmin,v)
                          Lmax,Umax,Vmax = max(Lmax,L),max(Umax,u),max(Vmax,v)
                    return Lmin,Umin,Vmin,Lmax,Umax,Vmax
                    
                  from numpy import linspace
                  
                  def getPoints(zz,toLuv,toRGB,x,y,z,c):
                    Lmin,Umin,Vmin,Lmax,Umax,Vmax = get_limits(toLuv)
                    L = Lmin + zz*(Lmax-Lmin)
                    for vv in linspace(0.0,1.0,num=50):
                      v = Vmax - (Vmax-Vmin)*vv
                      for uu in linspace(0.0,1.0,num=50):
                        u = Umin + (Umax-Umin)*uu
                        #print(u,v)
                        r,g,b = toRGB(L,u,v)
                        if valid_rgb(r,g,b): 
                          x.append(u)
                          y.append(v)
                          z.append(L)
                          c.append((r/255,g/255,b/255))
                          #print(u,v,L,)
                    return True
                  
                  def show3d(toLuv,toRGB):
                    Lmin,Umin,Vmin,Lmax,Umax,Vmax = get_limits(toLuv)
                    Lmin,Umin,Vmin,Lmax,Umax,Vmax = round(Lmin),round(Umin),round(Vmin),round(Lmax),round(Umax),round(Vmax)
                    from mpl_toolkits.mplot3d import Axes3D
                    import matplotlib.pyplot as plt
                    fig = plt.figure()
                    ax = fig.add_subplot(111, projection='3d')
                    
                    ax.set_xlabel('u*')
                    ax.set_xlim([Umin,Umax])
                    ax.set_ylabel('v*')
                    ax.set_ylim([Vmin,Vmax])
                    ax.set_zlabel('L*')
                    ax.set_zlim([Lmin,Lmax])
                    
                    x,y,z,c = [],[],[],[]
                    for zz in {0.1, 0.3, 0.5, 0.7, 0.8,  0.9, 0.95 }:
                      #x,y,z,c = getSurface(zz,toLuv,toRGB)
                      getPoints(zz,toLuv,toRGB,x,y,z,c)
                    ax.scatter(x, y, z, s=80, color=c, marker='o', alpha=1.0, linewidth=0)
                    plt.show()
                    fig.savefig('test.png')
                    plt.close(fig)
                    
                  if __name__ == '__main__':
                    import console as cs
                    cs.clear()
                    show3d(rgb_to_sLuv,sLuv_to_rgb)
                    
                  
                  
                  1 Reply Last reply Reply Quote 0
                  • jmv38
                    jmv38 last edited by

                    i use the ‘current’ appstore version of pythonista on ipad air ios 12.0.1 (not yet on 12.1.1)

                    1 Reply Last reply Reply Quote 0
                    • jmv38
                      jmv38 last edited by jmv38

                      ok guys, i nailed it: i was using a dictionnary for my zz so the order was random.

                      for zz in {0.1, 0.3, 0.5, 0.7, 0.9, 0.95 }:
                      

                      I changed it to an array

                      for zz in [0.1, 0.3, 0.5, 0.7, 0.9, 0.95 ]:
                      

                      and now the layers print in the specified order

                      my bad... :-(

                      1 Reply Last reply Reply Quote 0
                      • jmv38
                        jmv38 last edited by jmv38

                        the desired result:

                        Pretty cool, isn’t it? :-)

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors