Anwendungen II

Geografische Daten (Längen-/Breitengrad) verarbeiten

Die Datei california_cities.csv sollten Sie zuerst herunterladen und auf Ihrem Rechner speichern. Korrigieren Sie die Pfad-Angaben entsprechend, wenn Sie das Programm auf Ihrem Rechner laufen lassen. Alternativ benutzen Sie den unteren Link zu JupyterLab.

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

cities = pd.read_csv('/tmp/data/california_cities.csv')

# Extract the data we're interested in
lat, lon = cities['latd'], cities['longd']
population, area = cities['population_total'], cities['area_total_km2']

# Scatter the points, using size and color but no label
plt.scatter(lon, lat, label=None, c=np.log10(population), cmap='viridis', s=area, linewidth=0, alpha=0.5)
plt.axis()
plt.xlabel('longitude')
plt.ylabel('latitude')
plt.colorbar(label='log$_{10}$(population)')
plt.clim(3, 7)

# Here we create a legend:
# we'll plot empty lists with the desired size and label
for area in [100, 300, 500]:
    plt.scatter([], [], c='k', alpha=0.3, s=area, label=str(area) + ' km$^2$')
plt.legend(scatterpoints=1, frameon=False, labelspacing=1, title='City Area')

plt.title('California Cities: Area and Population');
plt.show()

Jupyter lab

Externe 3D-Datensätze in 3D und 2D darstellen

Die verwendeten Datensätze können heruntergeladen werden:

  • contourN.dat
  • import pandas as pd
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    # contourN.dat is a simple csv file with x,y,z values line by line
    data = pd.read_csv('contourN.dat', sep=',', names=['X', 'Y', 'Z'], index_col=False)
    """
    print(type(data))
    print(data)
    
             X        Y         Z
    0     -3.0 -3.00000 -0.001395
    1     -3.0 -2.97647 -0.001410
    2     -3.0 -2.95294 -0.001421
    3     -3.0 -2.92941 -0.001426
    4     -3.0 -2.90588 -0.001427
    ...    ...      ...       ...
    65531  3.0  2.90588 -0.001427
    65532  3.0  2.92941 -0.001426
    65533  3.0  2.95294 -0.001421
    65534  3.0  2.97647 -0.001410
    65535  3.0  3.00000 -0.001395
    
    [65536 rows x 3 columns]
    """
    
    x_num = len(data['X'].unique())# Anzahl x-Werte = 256
    y_num = len(data['Y'].unique())#        y-Werte = 256
    
    x = data['X'].values.reshape(x_num, -1)# Alle x-Werte 
    """
    print(type(x))
    print(x)
    
    [[-3.      -3.      -3.      ... -3.      -3.      -3.     ]
     [-2.97647 -2.97647 -2.97647 ... -2.97647 -2.97647 -2.97647]
     [-2.95294 -2.95294 -2.95294 ... -2.95294 -2.95294 -2.95294]
     ...
     [ 2.95294  2.95294  2.95294 ...  2.95294  2.95294  2.95294]
     [ 2.97647  2.97647  2.97647 ...  2.97647  2.97647  2.97647]
     [ 3.       3.       3.      ...  3.       3.       3.     ]]
    """
    
    y = data['Y'].values.reshape(y_num, -1)
    """
    print(type(y))
    print(y)
    
    [[-3.      -2.97647 -2.95294 ...  2.95294  2.97647  3.     ]
     [-3.      -2.97647 -2.95294 ...  2.95294  2.97647  3.     ]
     [-3.      -2.97647 -2.95294 ...  2.95294  2.97647  3.     ]
     ...
     [-3.      -2.97647 -2.95294 ...  2.95294  2.97647  3.     ]
     [-3.      -2.97647 -2.95294 ...  2.95294  2.97647  3.     ]
     [-3.      -2.97647 -2.95294 ...  2.95294  2.97647  3.     ]]
    """
    
    z = data['Z'].values.reshape((x_num, y_num))
    """
    print(type(z))
    print(z)
    
    [[-0.00139517 -0.00141026 -0.00142055 ... -0.0014158  -0.00140599  -0.00139517]
     [-0.00140599 -0.00141895 -0.00142705 ... -0.00142662 -0.00141895  -0.00141026]
     [-0.0014158  -0.00142662 -0.00143251 ... -0.00143251 -0.00142705  -0.00142055]
     ...
     [-0.00142055 -0.00142705 -0.00143251 ... -0.00143251 -0.00142662  -0.0014158 ]
     [-0.00141026 -0.00141895 -0.00142662 ... -0.00142705 -0.00141895  -0.00140599]
     [-0.00139517 -0.00140599 -0.0014158  ... -0.00142055 -0.00141026  -0.00139517]]
    """
    fig = plt.figure(figsize=(6,13.5))
    ax1 = fig.add_subplot(2,1,1,projection='3d')
    surf = ax1.plot_surface(x, y, z,cmap="hsv", lw=0.1, alpha=0.75, rstride=1, cstride=1)# row/column-Schrittweite
    
    # Plot projections of the contours for each dimension.  By choosing offsets
    # that match the appropriate axes limits, the projected contours will sit on
    # the 'walls' of the graph
    #cset = ax.contour(x, y, z, zdir='z', offset=0.02, cmap="hsv")
    cset = ax1.contour(x, y, z, zdir='z', offset=-0.02, cmap="magma")
    cset = ax1.contour(x, y, z, zdir='x', offset=-3, cmap="magma")
    cset = ax1.contour(x, y, z, zdir='y', offset=-3, cmap="magma")
    
    ax1.view_init(20, 25)#  theta, alpha (kippen, drehen in Grad)
    ax1.set_xlim(-3, 3)
    ax1.set_ylim(-3, 3)
    ax1.set_zlim(-0.02, 0.02)
    
    ax1.set_xlabel('X')
    ax1.set_ylabel('Y')
    ax1.set_zlabel('Z')
    
    ax2 = fig.add_subplot(2,1,2)
    ax2.contour(x, y, z, cmap='magma')
    ax2.axis('equal')
    plt.show()

    Iterationen mit komplexen Zahlen

    Ausgabe der Mandelbrotmenge in Originalgröße oder als Zoom in eien kleinen Bereich. Kann bei langsamen Rechnern fünf Minuten dauern!

    from PIL import Image    # pip3 install Pillow
    #import subprocess
    
    orig = input("Ausgabe in Originalgröße? (J/N) [N]: ")
    # drawing area (xa < xb and ya < yb)
    if orig.lower() == 'j': 
      xa = -2.0
      xb = 1.0
      ya = -1.5
      yb = 1.5
      imgy = 1000
    else:
      xa = -0.1716
      xb = -0.1433
      ya = 1.022
      yb = 1.044
      imgy = 750
    maxIt = 1024 # iterations   512, 1024
    
    # image size
    imgx = 1000
    
    image = Image.new("RGB", (imgx, imgy))
    
    for y in range(imgy):
        cy = y * (yb - ya) / (imgy - 1)  + ya
        for x in range(imgx):
            cx = x * (xb - xa) / (imgx - 1) + xa
            c = complex(cx, cy)
            z = 0
            for i in range(maxIt):
                if abs(z) > 2.0: break 
                z = z * z + c 
            r = i % 4 * 6
            g = i % 8 * 32
            b = i % 16 * 16
            if orig.lower() == 'j': 
                image.putpixel((x, y), b * 65536 + g * 256 + r)
            else:
                image.putpixel((x, y), (i % 256,i % 256,i % 256))
    
    image.save("mandel.png", "PNG")
    image.show()
    #p = subprocess.run(["open", "mandel.png"], capture_output=True)
    #print(p.stdout.decode(),p.stderr.decode())
    #webbrowser.open(mandel.png)

    Jupyter lab

    Variante 2

    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.ion()# inline on
    def mandelbrot_set(width, height, zoom=1, x_off=0, y_off=0, niter=256):
        w,h = width, height
        pixels = np.arange(w*h, dtype=np.uint16).reshape(h, w)
        for x in range(w): 
            for y in range(h):
                zx = 1.5*(x + x_off - 3*w/4)/(0.5*zoom*w)
                zy = 1.0*(y + y_off - h/2)/(0.5*zoom*h)
                z = complex(zx, zy)
                c = complex(0, 0)
                for i in range(niter):
                    if abs(c) > 4: break
                    c = c**2 + z
                color = (i << 21) + (i << 10)  + i * 8
                pixels[y,x] = color  
        return pixels
    
    def display(width=2048, height=1536, x_off=0, y_off=0, cmap='ocean', zoom=1):
        pixels = mandelbrot_set(width, height, zoom=zoom, x_off=x_off, y_off=y_off)
        plt.axis('off')
        plt.imshow(pixels, cmap=cmap)
        plt.show()
    
    #display(zoom=2.0, x_off=-300)
    display()
    plt.ioff()

    Jupyter lab

    Simulationen

    Das Wachstum von Wasserpflanzen lässt sich mit folgendem Programm simulieren:

    from PIL import Image    # pip3 install Pillow
    #import subprocess
    import random
    
    #random.randint(0, 100)
    
    def StartPunkt():
    #  x = int(random.randint(MaxX//4,3*MaxX//4))
      x = random.randint(1,4) * MaxX//5
      if x < 10:
        x = 10
      if x >= MaxX:
        x = MaxX - 10
      y = 2 # int(MaxYHalbe)
      return x,y
    
    def Angekommen(x, y):
      if y >= MaxY-1 or x <= 0 or x > MaxX-1:
        return True  
      for i in range(x-1,x+2):
        for j in range(y,y+2):    
          if image.getpixel((i,j)) > 0:
            return True
      return False
      
    def NeueKoordinatenBestimmen (x, y):
      x = x + random.randint(0,2)-1
      y = y + random.randint(0,2)   # nur nach oben
      return x,y
    
    MaxX = 500
    MaxXHalbe = MaxX / 2
    MaxY = 250
    MaxYHalbe = MaxY / 2
    image = Image.new("L", (MaxX, MaxY))
    for i in range(MaxX):
      image.putpixel((i, 0), 255)
      image.putpixel((i, MaxY-1), 255)
    
    for i in range(10000):
        if i % 1000 == 0:
          print(i)
        x,y = StartPunkt()
        while not Angekommen(x,y):
          x,y = NeueKoordinatenBestimmen(x,y)
          if (x < 0) or (x >= MaxX-1):
            x,y = StartPunkt()
        image.putpixel((x, y), 255)
    
    image.save("wasser.png", "PNG")
    image.show()
    #p = subprocess.run(["open", "wasser.png"], capture_output=True)
    #print(p.stdout.decode(),p.stderr.decode())

    Nächste Einheit: 09 Datenbanken