Je n'arrive pas à comprendre comment obtenir la ligne de régression linéaire (alias la ligne de meilleur ajustement) pour couvrir toute la largeur du graphique. Il semble simplement remonter le point de données le plus éloigné à gauche et le point de données le plus éloigné à droite, et pas plus loin. Comment résoudre ce problème?
import matplotlib.pyplot as plt import numpy as np from scipy import stats from scipy.interpolate import * import MySQLdb # connect to MySQL database def mysql_select_all(): conn = MySQLdb.connect(host='localhost', user='root', passwd='XXXXX', db='world') cursor = conn.cursor() sql = """ SELECT GNP, Population FROM country WHERE Name LIKE 'United States' OR Name LIKE 'Canada' OR Name LIKE 'United Kingdom' OR Name LIKE 'Russia' OR Name LIKE 'Germany' OR Name LIKE 'Poland' OR Name LIKE 'Italy' OR Name LIKE 'China' OR Name LIKE 'India' OR Name LIKE 'Japan' OR Name LIKE 'Brazil'; """ cursor.execute(sql) result = cursor.fetchall() list_x = [] list_y = [] for row in result: list_x.append(('%r' % (row[0],))) for row in result: list_y.append(('%r' % (row[1],))) list_x = list(map(float, list_x)) list_y = list(map(float, list_y)) fig = plt.figure() ax1 = plt.subplot2grid((1,1), (0,0)) p1 = np.polyfit(list_x, list_y, 1) # this line refers to line of regression ax1.xaxis.labelpad = 50 ax1.yaxis.labelpad = 50 plt.plot(list_x, np.polyval(p1,list_x),'r-') # this refers to line of regression plt.scatter(list_x, list_y, color = 'darkgreen', s = 100) plt.xlabel("GNP (US dollars)", fontsize=30) plt.ylabel("Population(in billions)", fontsize=30) plt.xticks([1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000], rotation=45, fontsize=14) plt.yticks(fontsize=14) plt.show() cursor.close() mysql_select_all()
3 Réponses :
MySQLdb
n'est pas installé sur mon système, je ne peux donc pas exécuter votre code en tant que tel, mais les lignes de code suivantes devraient certainement fonctionner.
MODIFIER en fonction des commentaires: vous devez également définir les limites x
x_low = 0.9*min(list_x) x_high = 1.1*max(list_x) x_extended = np.linspace(x_low, x_high, 100) p1 = np.polyfit(list_x, list_y, 1) # this line refers to line of regression ax1.xaxis.labelpad = 50 ax1.yaxis.labelpad = 50 plt.plot(x_extended, np.polyval(p1,x_extended),'r-') # this line refers to line of regression plt.xlim(x_low, h_high)
Ça montrait toujours la même chose
@NickT: Essayez x_extended = np.linspace (500000, 10000000, 100)
et faites-le moi savoir
J'ai essayé ça. Il a juste changé les étiquettes des axes
@NickT: Quelle est la valeur x minimale et maximale de vos données?
min est 151697, max est 8510700
Ainsi, même si vous utilisez x_extended = np.linspace (15000, 10510700, 100)
, vous ne voyez aucune extension?
Malheureusement, il ne s'est pas étendu
Essayez d'ajouter plt.xlim (15000, 10510700) et vérifiez si vous voyez quelque chose. Peut-être que l'axe n'est pas étendu. Malheureusement, je ne peux pas exécuter votre code
Oui!!!!!! Cette dernière chose l'a fait. Bazingaa, merci!
@NickT: Heureux de vous aider. Je vous en prie.
Ouais ne devriez-vous pas modifier la réponse pour l'inclure?
@NickT: je l'ai déjà fait;)
@NickT: Les versions 0.9 et 1.1 fonctionnent-elles pour vous après avoir défini les limites? Si oui, alors je laisse ma réponse inchangée pour x_low et x_high
Je pense que cela ne fonctionnerait que dans les cas où aucune des données x n'est négative. En outre, il suppose en quelque sorte que la ligne est inclinée de telle sorte qu'elle toucherait d'abord les épines verticales plutôt que les horizontales.
Si vous souhaitez que votre tracé ne dépasse pas vos données sur l'axe des x, procédez simplement comme suit:
fig, ax = plt.subplots() ax.margins(x=0) # Don't use plt.plot ax.plot(list_x, np.polyval(p1,list_x),'r-') ax.scatter(list_x, list_y, color = 'darkgreen', s = 100) ax.set_xlabel("GNP (US dollars)", fontsize=30) ax.set_ylabel("Population(in billions)", fontsize=30) ax.set_xticks([1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000], rotation=45, fontsize=14) ax.tick_params(axis='y', labelsize=14)
Puisque vous n'avez pas inclus les données, voici un exemple simple utilisant des données artificielles. L'idée ici est de trouver quelle serait la valeur de la ligne de régression aux limites x de votre tracé, puis de forcer matplotlib à ne pas ajouter le 'buffer' normal aux bords des données.
import numpy as np import matplotlib.pyplot as plt x = [1, 1.8, 3.3, 3.5, 5.5, 6.1] y = [1, 2.1, 3.0, 3.7, 5.2, 6.4] p1 = np.polyfit(x, y, 1) plt.scatter(x, y) xlims = plt.xlim() x.insert(0, xlims[0]) y.insert(0, np.polyval(p1, xlims[0])) x.append(xlims[1]) y.append(np.polyval(p1, xlims[1])) plt.plot(x, np.polyval(p1,x), 'r-', linewidth = 1.5) plt.xlim(xlims) plt.show()
évaluer votre polynôme à des valeurs de plus en plus petites de
x
?comment pourrais-je faire ça?
plt.plot ([little_x, big_x], np.polyval (p1, [little_x, big_x]), 'r-')
little_x, big_x ... sont ces nombres arbitraires ou parlez-vous min x value max x value?
Ils correspondent à la durée que vous souhaitez que la ligne englobe.
Ce problème est en quelque sorte beaucoup plus difficile qu'il n'y paraît à première vue. J'ai marqué cela comme un double car dans les questions liées, les réponses sont plus généralement applicables.
En effet. Cela semble être un double. La plupart des personnes ayant ce problème rechercheront «régression linéaire» ou «ligne de meilleur ajustement». Comme je l'ai fait. Le titre est trop éloigné de l'autre poste. Vous auriez besoin de creuser un peu pour le trouver