Étudier les mathématiques avec Python: dessiner un graphe sympy (scipy) avec matplotlib

La visualisation est importante

Il est souvent difficile de comprendre intuitivement à quoi ressemblera le résultat même s'il est obtenu par une fonction. Par conséquent, dessiner un graphique est la première étape de l'analyse et de la réflexion. Pour le mémo japonais de matplotlib, voir ici. L'intrigue de sympy est ici. Officiel J'ai eu du mal en le regardant.

import

import sympy as sym
sym.init_printing()
Pi = sym.S.Pi #Pi
E = sym.S.Exp1 #Bas du logarithme naturel
I = sym.S.ImaginaryUnit #Unité imaginaire

#Définition des variables à utiliser(Toute une lettre minuscule est un symbole)
(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) = sym.symbols('a b c d e f g h i j k l m n o p q r s t u v w x y z')

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

from mpl_toolkits.mplot3d import Axes3D

Faites de votre mieux en couleur

La liste des couleurs a été pré-générée par un autre programme afin qu'il s'agisse d'un anneau avec une luminosité constante dans l'espace colorimétrique L * a * b *. Conçu avec une marge de sécurité pour le contraste plutôt que l'éclat des couleurs, la faiblesse des couleurs n'est pas prise en compte. Chaque liste se compose de 37 chaînes HEX. Le nombre 37 a été sélectionné car il s'agit du nombre premier le plus proche de 36, qui est le nombre qui avance de 360 degrés d'un tour de 10 degrés. (S'il est de 37, il avance de 9,73 degrés par un.) Puisqu'il s'agit d'un nombre premier, peu importe comment vous choisissez la couleur initiale et le nombre d'étapes (il doit s'agir d'une racine primitive), ce sera toujours un ** groupe de patrouilles ** qui passe par 37 couleurs une par une. Il s'agit d'une correspondance intuitive dont la phase avance d'environ 10 pas * 10 degrés. Autant que possible, la même couleur n'apparaît pas et le cycle est long.

def generator_p(start): #Un générateur pour générer des couleurs dans l'ordre si un argument est spécifié, sinon.
    prime = 37 #Nombre de listes(Puisqu'il s'agit d'un nombre premier, ce sera toujours la période maximale, peu importe ce que vous spécifiez pour primitive.)
    primitive = 8 #La source(La teinte par étape est primitive* 37/Aller à 360 degrés)
    g0 = start #Source de départ(Ce qui est réellement retourné est g0* primitive)
    while True:
        val = yield g0
        if val: #Si un argument est passé au générateur, il sera réinitialisé comme source de départ.
            g0 = val
        g0 += primitive
        if g0 >= prime: #Prenez le surplus
            g0 -= prime
gen_hexnum = generator_p(0) #Mettez la couleur initiale dans l'argument
gen_hexnum.__next__() #Initialisation du générateur

def hexNum(num, type): #Liste des couleurs
    #Couleur de base(Une couleur calme qui peut être utilisée universellement sur fond blanc)
    color_basic = ['#9c1954', '#9e1a46', '#9d1e38', '#9a252a', '#962d1c', '#8f350d', '#873c00',
                   '#7d4300', '#734900', '#674f00', '#5b5300', '#4d5700', '#3e5b00', '#2b5d00',
                   '#0f6009', '#00611c', '#00632b', '#00643a', '#006449', '#006558', '#006567',
                   '#006575', '#006482', '#00648e', '#006298', '#0060a0', '#005ea6', '#005baa',
                   '#0056aa', '#0051a9', '#2f4ca4', '#50459d', '#673d94', '#78358a', '#862d7d', '#902470', '#981e62']
    #Couleurs très saturées(Il se démarque, mais vous ne devriez pas l'utiliser beaucoup.)
    color_vivid = ['#ffadc7', '#ffadbc', '#ffaeb2', '#ffb0a8', '#ffb29e', '#ffb596', '#f9b88f',
                   '#f1bc8a', '#e9bf86', '#dfc385', '#d5c685', '#caca87', '#becd8b', '#b2cf90',
                   '#a6d298', '#99d4a0', '#8dd5aa', '#80d7b4', '#74d7bf', '#6ad8ca', '#61d8d5',
                   '#5bd7e0', '#59d6e9', '#5dd5f2', '#65d3f9', '#71d1ff', '#7fceff', '#8ecbff',
                   '#9ec8ff', '#afc4ff', '#bec1ff', '#cdbdfd', '#dab9f7', '#e6b6ef', '#f0b3e6', '#f9b0dc', '#ffaed2']
    #Couleur claire(Non utilisé sur fond blanc. Supposé être utilisé sur un fond noir.)
    color_thin = ['#ffc3d5', '#ffc3cd', '#ffc3c5', '#ffc4be', '#ffc6b7', '#ffc8b1', '#fbcaac',
                  '#f5cca9', '#efcfa6', '#e8d2a5', '#e0d4a5', '#d8d7a6', '#cfd9a9', '#c6dbad',
                  '#bdddb3', '#b5deb9', '#ace0c0', '#a5e0c7', '#9ee1cf', '#98e1d7', '#94e1df',
                  '#92e1e6', '#92e0ed', '#94dff4', '#99def9', '#9fdcfd', '#a7daff', '#b1d8ff',
                  '#bbd5ff', '#c5d3ff', '#cfd0ff', '#dacdfc', '#e3cbf7', '#ecc8f2', '#f3c6eb', '#f9c5e4', '#fec4dc']

    if (type == 'thin'):
        hex_list = color_thin
    elif (type == 'vivid'):
        hex_list = color_vivid
    else:
        hex_list = color_basic
    if num is not None:
        gen_hexnum.send(num)
    return hex_list[gen_hexnum.__next__()]

Création d'une fonction de tracé graphique à 2 dimensions: fonction explicite à 1 variable

def plot(func, xrange, ylim=None, xlog=None, ylog=None, cn=None, ct='basic', close=None, figs=None, simbol=x):
    if figs:
        plt.figure(figsize=figs)
    X = np.arange(xrange[0], xrange[1], xrange[2])
    if hasattr(func, "subs"): # sympy
        Y = [func.subs([(simbol, K)]) for K in X]
    else: # scipy
        Y = [func(K) for K in X]
    if ylim:
        plt.ylim(ylim)
    if xlog:
        plt.xscale('log')
    else:
        plt.xscale('linear')
    if ylog:
        plt.yscale('log')
    else:
        plt.yscale('linear')
    plt.plot(X, Y, color=hexNum(cn, ct))
    if close:
        plt.show()
        plt.close()

Le simple matplotlib.plot est déroutant, j'ai donc créé une fonction qui n'englobe que les arguments fréquemment utilisés. Il est plus facile à utiliser si vous donnez la fonction, la largeur et la couleur, puis demandez-les.

F = sym.sin(x)/x
G = sym.cos(x)/x
plot(F, (-10, 10, 0.1), cn=0, figs=(10, 6))
plot(G, (-10, 10, 0.1))
plot(F+0.2, (-10, 10, 0.1))
plot(F+0.4, (-10, 10, 0.1))
plot(F+0.6, (-10, 10, 0.1))
plot(F+0.8, (-10, 10, 0.1))
plot(F+1.0, (-10, 10, 0.1))
def A(x):
    return np.sin(x)/x
plot(A, (-10, 10, 0.1))
plot(lambda X: (X/9.0)**2, (-10, 10, 0.1), (-0.5, 1.5), close=True)

hiki.png Pour utiliser sympy confortablement, je veux utiliser toutes les lettres minuscules comme symboles, donc Les noms de fonction et les variables de boucle sont intentionnellement mis en majuscules. Effet de codage couleur par couleur, jugement automatique des fonctions sympy et numpy par hasattr, Avec l'argument close, toutes les options doivent être écrites ensemble à la fin. Je suis satisfait car je peux le tracer assez intuitivement. Cependant, en regardant le graphique, les pôles de $ \ frac {\ cos (x)} {x} $ sont étranges. L'atmosphère est que la ligne au milieu de $ - \ infty \ longrightarrow \ infty $ est dessinée. Y a-t-il une solution?

Création d'une fonction de tracé graphique bidimensionnel: affichage des variables du médiateur

def plotp(func, t_range=(-4, 4, 100), axis=[-4, 4, -4, 4],
          xlog=None, ylog=None, cn=None, ct='basic', close=None, figs=None, simbol=t):
    if figs:
        plt.figure(figsize=figs)
    X, Y = func
    t_ndarray = np.linspace(t_range[0], t_range[1], t_range[2]) # ndarray
    if hasattr(X, "subs"): # sympy
        Xp = np.array([float(sym.N(X.subs([(simbol, T)]))) for T in t_ndarray])
        Yp = np.array([float(sym.N(Y.subs([(simbol, T)]))) for T in t_ndarray])
    else: # scipy
        Xp = [X(K) for K in t_ndarray]
        Yp = [Y(K) for K in t_ndarray]
    plt.axis(axis)
    if xlog:
        plt.xscale('log')
    else:
        plt.xscale('linear')
    if ylog:
        plt.yscale('log')
    else:
        plt.yscale('linear')
    plt.plot(Xp, Yp, color=hexNum(cn, ct))
    if close:
        plt.show()
        plt.close()

La différence avec plot () est que Func est passé sous la forme d'une liste de deux fonctions et qu'un axe spécifiant les zones x et y est ajouté. Par convention, t est le symbole par défaut. De plus, comme troisième plage de t, elle est spécifiée par le nombre de divisions au lieu de la taille du pas.

X = t**2 * sym.sin(t)
Y = t**2 * sym.cos(t)
plotp([X, Y], (-4 * np.pi, 4 * np.pi, 400), [-100, 100, -100, 100], figs=(6, 6), close=True)
plotp([lambda T: T * np.sin(T), lambda T: T * np.cos(T)], (-4 * np.pi, 4 * np.pi, 400), [-12, 12, -10, 10],
cn=14, figs=(6, 6), close=True)

hiki2.png hiki3.png

Sympy et Scipy ont travaillé.

Création d'une fonction de tracé graphique à 2 dimensions: fonction implicite à 2 variables

C'est une fonction exprimée au format $ F (x, y) = 0 $. Il semble difficile de gérer directement les fonctions implicites. Utilisez donc plot_implicit de sympy tel quel.

F = x**3 + y**2 -1
sym.plot_implicit(F, (x, -2, 2), (y, -2, 2), line_color=hexNum(2, 'basic'))

hiki4.png Il s'agit d'une équation de courbe elliptique. La couleur semble utilisable, mais elle est claire.

F = x**3 - 2 * x + y**2 > 0
sym.plot_implicit(F, (x, -2, 2), (y, -2, 2), line_color=hexNum(2, 'thin'))

hiki5.png

L'avantage est que l'inégalité peut être utilisée.

Création d'une fonction de tracé graphique en 3 dimensions: fonction explicite à 2 variables

Une fonction de la forme $ z = f (x, y) $.

from matplotlib import cm

def plot3D(func, xrange=(-2, 2, 0.1), yrange=(-2, 2, 0.1), ptype='plot', simbol=[x, y]):
    fig = plt.figure()
    ax = Axes3D(fig)
    if ptype == 'plot':
        ax.plot(func[0], func[1], func[2])
        plt.show()
        plt.close()
        return
    X = np.arange(xrange[0], xrange[1], xrange[2])
    Y = np.arange(yrange[0], yrange[1], yrange[2])
    Xmesh, Ymesh = np.meshgrid(X, Y)
    if hasattr(func, "subs"): # sympy
        Z = np.array([np.array([float(sym.N(func.subs([(simbol[0], K), (simbol[1], L)]))) for K in X]) for L in Y])
    else: # scipy
        Z = func(Xmesh, Ymesh)

    if ptype == 'surface':
         ax.plot_surface(Xmesh, Ymesh, Z, cmap=cm.bwr)
    elif ptype == 'wireframe':
        ax.plot_wireframe(Xmesh,Ymesh, Z)
    elif ptype == 'contour':
        ax.contour3D(X, Y, Z)
    plt.show()
    plt.close()
plot3D(lambda T, U: T * U * np.sin(T), (-4, 4, 0.25), (-4, 4, 0.25), 'surface')

plot3D((x ** 2 - 3 - y ** 2), (-4, 4, 0.25), (-4, 4, 0.25), 'surface')
plot3D((x ** 2 - 3 - y ** 2), (-4, 4, 0.25), (-4, 4, 0.25), 'wireframe')
plot3D((x ** 2 - 3 - y ** 2), (-4, 4, 0.25), (-4, 4, 0.25), 'contour')

hiki6.png hiki7.png

La couleur par défaut est utilisée pour la 3D car il vaut mieux voir les hauts et les bas avec une différence de luminosité. J'ai tracé la fonction de la selle de cheval qui apparaît souvent dans la figure de l'univers à courbure négative.

Création de la fonction de tracé graphique 3D: affichage des variables de médiation

def plotp3(func, simbol=[t], rangeL=[(-4, 4, 100)]):
    X, Y, Z = func
    t1 = simbol[0]
    if len(simbol) >= 2:
        u1 = simbol[1]
    t_rangeL = rangeL[0]
    t_ndarray = np.linspace(t_rangeL[0], t_rangeL[1], t_rangeL[2]) # ndarray
    
    if len(rangeL) >= 2:
        u_rangeL = rangeL[1]
        u_ndarray = np.linspace(u_rangeL[0], u_rangeL[1], u_rangeL[2]) # ndarray
    if len(rangeL) == 1:
        Xp = np.array([float(sym.N(X.subs([(t1, T)]))) for T in t_ndarray])
        Yp = np.array([float(sym.N(Y.subs([(t1, T)]))) for T in t_ndarray])
        Zp = np.array([float(sym.N(Z.subs([(t1, T)]))) for T in t_ndarray])
    else:
        Xp = np.array([float(sym.N(X.subs([(t1, T), (u1, U)]))) for T in t_ndarray for U in u_ndarray])
        Yp = np.array([float(sym.N(Y.subs([(t1, T), (u1, U)]))) for T in t_ndarray for U in u_ndarray])
        Zp = np.array([float(sym.N(Z.subs([(t1, T), (u1, U)]))) for T in t_ndarray for U in u_ndarray])

    fig = plt.figure()
    ax = Axes3D(fig)
    ax.plot(Xp, Yp, Zp)
    plt.show()
    plt.close()
X = 2*sym.cos(t)
Y = 5*sym.sin(t)
Z = t
plotp3([X, Y, Z], [t], [(-5 * np.pi, 5 * np.pi, 200)])

X = (5+2*sym.cos(t))*sym.cos(u)
Y = (5+2*sym.sin(u))*sym.sin(u)
Z = 2*sym.sin(t)-u/sym.oo
plotp3([X, Y, Z], [t, u], [(-np.pi, np.pi, 40), (-np.pi, np.pi, 40)])

hiki8.png

Je suis fatigué de cette région. La 3D est sympa par défaut, donc ça va.

X = 2*sym.cos(t)
Y = 5*sym.sin(t)
Z = t
sym.plotting.plot3d_parametric_line(X, Y, Z, (t, -5*np.pi, 5*np.pi))

X = (5+2*sym.cos(t))*sym.cos(u)
Y = (5+2*sym.sin(u))*sym.sin(u)
Z = 2*sym.sin(t)-u/sym.oo
sym.plotting.plot3d_parametric_surface(X, Y, Z, (t, -np.pi, np.pi), (u, -np.pi, np.pi))

hiki9.png

Recommended Posts

Étudier les mathématiques avec Python: dessiner un graphe sympy (scipy) avec matplotlib
[Python] Comment dessiner un graphique linéaire avec Matplotlib
Dessinez un graphique lâche avec matplotlib
Dessinez une surface plane avec un graphique 3D matplotlib
[Python] Dessinez un graphe orienté avec Dash Cytoscape
Dessinez un graphique avec NetworkX
Dessinez un graphique avec networkx
Dessinez de force quelque chose comme un organigramme avec Python, matplotlib
[Python] Comment dessiner un diagramme de dispersion avec Matplotlib
Manuel de graphisme Python avec Matplotlib.
Tracez un graphe avec Julia + PyQtGraph (2)
Tracez un graphique avec Julia + PyQtGraph (1)
Dessinez un graphique avec Julia + PyQtGraph (3)
Dessinez un graphique avec des pandas + XlsxWriter
Faisons un graphe avec python! !!
Dessinez Riapnov Fractal avec Python, matplotlib
Dessinez un graphique avec l'interface graphique PySimple
[Python] Définissez la plage du graphique avec matplotlib
Comment dessiner un graphique avec Matplotlib
Dessiner un cœur avec Python Partie 2 (SymPy Edition)
Dessinez un graphique avec PyQtGraph Part 1-Drawing
Créer un graphique avec des bordures supprimées avec matplotlib
(Matplotlib) Je veux dessiner un graphique avec une taille spécifiée en pixels
Comment dessiner un graphique à barres qui résume plusieurs séries avec matplotlib
Dessiner un graphique d'une fonction quadratique en Python
Dessinez un graphique avec des étiquettes japonaises dans Jupyter
Comment dessiner un graphique à 2 axes avec pyplot
[Python] axe limite du graphe 3D avec Matplotlib
Lire les données csv Python avec Pandas ⇒ Graphique avec Matplotlib
Dessinez un graphique avec les paramètres PyQtGraph Partie 3-PlotWidget
Dessinez un graphique en traitant avec Pandas groupby
Essayez de dessiner une courbe de vie avec python
[Python] Comment dessiner plusieurs graphiques avec Matplotlib
[Python] Dessinez un Mickey Mouse avec une tortue [Débutant]
Dessinez un graphique avec les paramètres PyQtGraph Part 4-PlotItem
Dessinez un graphique avec PyQtGraph Partie 6 - Affichage d'une légende
[Python] Comment dessiner un histogramme avec Matplotlib
Créer un diagramme de dispersion 3D avec SciPy + matplotlib (Python)
Visualiser grib2 sur une carte avec python (matplotlib)
Dessinez une ligne de pliage / diagramme de dispersion avec python matplotlib pour fichier CSV (2 colonnes)
Carte thermique par Python + matplotlib
Graphique de bande avec matplotlib
Dessiner un graphique avec python
Dessinez un graphique avec PyQtGraph Partie 5-Augmentez l'axe Y
[Python] Dessinez un diagramme de relation de balises Qiita avec NetworkX
[Python] Comment créer un histogramme bidimensionnel avec Matplotlib
Dessinez un graphique avec PyQtGraph Partie 2 - Paramètres de tracé détaillés
[Python] Road to the Serpent (5) Jouez avec Matplotlib
J'ai créé un graphique à barres empilées avec matplotlib de Python et ajouté une étiquette de données
[Python] Résoudre des équations avec sympy
Graphique des données Excel avec matplotlib (1)
J'ai écrit rapidement un programme pour étudier la DI avec Python ①
Dessiner un fichier netCDF avec python
Étudiez Python avec Google Colaboratory
Créons un diagramme PRML avec Python, Numpy et matplotlib.
Méthode de dessin graphique avec matplotlib
Traitement de fichiers multiples avec Kivy + Matplotlib + Draw Graph sur GUI
Graphique des données Excel avec matplotlib (2)