How to avoid zigzag lines in matplotlib pyplot.plot? - python

X = (6 * np.random.rand(10, 1) - 3)
y_cap = (0.44530754 * X**2)+(1.01366334 * X)+0.13309963
plt.plot(X, y_cap, ls = '--')
I'm solving a polynomial regression problem (degree=2). I got the coefficients of X, X^2, and performed the polynominal regression. And now when I tried to plot using the above code I got these lines instead of a curve. How to solve this?

This happens because your X values are not ordered. Just do this before calculating y_cap:
X = np.sort(X, 0)
Then it will work. Full example:
import numpy as np
import matplotlib.pyplot as plt
X = (6 * np.random.rand(10, 1) - 3)
X = np.sort(X, 0)
y_cap = (0.44530754 * X**2)+(1.01366334 * X)+0.13309963
plt.plot(X, y_cap, ls = '--')
plt.show()

Related

matplotlib plotting multiple lines [duplicate]

X = (6 * np.random.rand(10, 1) - 3)
y_cap = (0.44530754 * X**2)+(1.01366334 * X)+0.13309963
plt.plot(X, y_cap, ls = '--')
I'm solving a polynomial regression problem (degree=2). I got the coefficients of X, X^2, and performed the polynominal regression. And now when I tried to plot using the above code I got these lines instead of a curve. How to solve this?
This happens because your X values are not ordered. Just do this before calculating y_cap:
X = np.sort(X, 0)
Then it will work. Full example:
import numpy as np
import matplotlib.pyplot as plt
X = (6 * np.random.rand(10, 1) - 3)
X = np.sort(X, 0)
y_cap = (0.44530754 * X**2)+(1.01366334 * X)+0.13309963
plt.plot(X, y_cap, ls = '--')
plt.show()

Add color to line plot in matplotlib depending on given values [duplicate]

This question already has answers here:
How to plot a gradient color line in matplotlib?
(7 answers)
Closed 3 years ago.
So I have a normal scatter plot:
import numpy as np
import matplotlib.pyplot as plt
import random
x = np.random.random_sample((100,))
x = np.sort(x)
y = x + np.sin(np.pi * x)
z = 5 * x
fig = plt.figure()
plot = plt.scatter(x, y, s= 10, c = z, cmap='coolwarm')
fig.colorbar(plot)
plt.grid(True, 'both')
plt.show()
that produces a plot something like this
However, I would really like to add a line to scatter and connect these points. It may sound ridiculous since it is easy to follow the points in given case, but imagine if the data would be more scattered and possibly multiple datasets ...
So my goal is to add a line to the scatter above, but the color of the line should change according to value of 'z', the same way scatter plot does. Is that even possible?
EDIT:
The x, y, z provided above is just random data to explain the problem. In reality, you can imagine the points (x, y) coordinates are given from an experiment meaning in general there is no relation between x, y, z or even if it is, it is NOT known upfront.
You can add another scatterplot using np.linspace() function:
import numpy as np
import matplotlib.pyplot as plt
import random
x = np.random.random_sample((100,))
x = np.sort(x)
y = x + np.sin(np.pi * x)
z = 5 * x
fig = plt.figure()
plot = plt.scatter(x, y, s= 10, c = z, cmap='coolwarm')
fig.colorbar(plot)
plt.grid(True, 'both')
# add another scatterplot
x_line = np.linspace(np.min(x), np.max(x), num=1000)
y_line = x_line + np.sin(np.pi * x_line)
z_line = 5 * x_line
plt.scatter(x_line, y_line, c=z_line, s=0.1, cmap='coolwarm')
plt.show()

Python plotting trigonometrical func

I have a function 2*x*arcctg(x) - 1, and i try to plot it in Python:
import os
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, np.pi / 2)
y = 2 * x * np.cos(2 * x) / np.sin(2 * x)
plt.plot(x, y)
plt.axis('tight')
plt.show()
but it's plot smthg like that:
and when i plot it in wolfram it looks:
What am i doing wrong?
The function should be:
2*x*arcctg(x) - 1
But arcctg(x) is not cos(2x)/sin(2x) (the expression you describe in your code). A ctg is the co-tangens, so cos(x)/sin(x). So that means that arcctg(x) is arctan(1/x).
So you can use:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, np.pi / 2)
y = 2 * x * np.arctan(1/x) - 1
plt.plot(x, y)
plt.axis('tight')
plt.show()
This produces the following plot:
Which matches with the plot in the question.
In case you want to make the plot look more than the one in Wolfram Alpha, you can like #MSeifert says, set the range from -pi/2 to pi/2, like:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-np.pi / 2, np.pi / 2, 1000)
y = 2 * x * np.arctan(1/x) - 1
plt.plot(x, y)
plt.axis('tight')
plt.show()
this then produces:

Determine plot smoothing by a parameter

I want to create a plot showing both the real data and a smoothed version of the data. Now, I am using the following script:
import pandas as pd
import matplotlib.pyplot as plt
# DataFrame of 321 values
df = pd.read_csv('data.csv')
r = df.rolling(window=10, center=True, on='Value').mean()
fig = plt.figure()
ax = df['Value'].plot(style='--', c='b', alpha=0.5)
r.plot(ax=ax, legend=0, c='b')
plt.show()
However, I would like this to work similarly to e.g. TensorBoard. There, you specify a smoothing parameter between 0 and 1 which changes the window of the rolling mean, 0 being no smoothing and 1 being extreme smoothing. How is this done? Can I also do this in Python?
It seems that you can use scipy.interpolate package to add smoothness to your data, something like this:
from scipy.interpolate import spline
# 300 represents number of points to make between T.min and T.max
# you can use other number to adjust smoothness
axnew = np.linspace(df['Value'].min(), df['Value'].max(), 300)
power_smooth = spline(df['Value'], df['y_Value'], axnew)
plt.plot(xnew, power_smooth)
plt.show()
Sample from docs:
Cubic-spline
>>> x = np.arange(0, 2 * np.pi + np.pi / 4, 2 * np.pi / 8)
>>> y = np.sin(x)
# s parameter for adjust the smoothness
>>> tck = interpolate.splrep(x, y, s=0)
>>> xnew = np.arange(0, 2 * np.pi, np.pi / 50)
>>> ynew = interpolate.splev(xnew, tck, der=0)
Related question: Plot smooth line with PyPlot
Update: #ImportanceOfBeingErnest noticed that spline is depreciated in the newest version of scipy, so you should investigate the splev and splrep. Some samples can be found here.

How to convert 1D arrays into 2D arrays for the plot_surf() function to work correctly in python3?

The original code written in the following format was running without any error yet it did not produce the desired 2d-function plot/surface. In fact, I was getting the 3d space with all the titles and labels but without actual 2d plot. I have tried to check the output by print() function at each step. It seems that the code produces correctly the z array but surf() is not responding accordingly. So, the question should have been instead "What method is missing in the code so that Surface() is not responding accordingly?"
import sys
import matplotlib
matplotlib.use('SVG')
import matplotlib.pyplot as pyplot
from matplotlib.ticker import MaxNLocator
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from numpy import array as ar
import random
from scipy import linspace, meshgrid, arange, empty, concatenate, newaxis, shape
import math
fig =pyplot.figure()
ax = fig.gca(projection='3d')
N = 10000
data1 = [random.random() for i in range(N)]
x1 = ar(data1)
data2 = [random.random() for i in range(N)]
x2 = ar(data2)
a = 2.000000
y1 = np.sqrt((-1.000000) * a * np.log(x1)) * np.cos(2 * math.pi * x2)
y2 = np.sqrt((-1.000000) * a * np.log(x1)) * np.sin(2 * math.pi * x2)
gaussian1 = math.pow(2 * math.pi, (-1.000000 / a)) * np.exp((-1.000000 / a) * y1**a)
gaussian2 = math.pow(2 * math.pi, (-1.000000 / a)) * np.exp((-1.000000 / a) * y2**a)
z = gaussian1 * gaussian2
surf = ax.plot_surface(x1, x2, z, rstride=1, cstride=1, cmap=cm.jet, linewidth=1.0)
fig.colorbar(surf)
title = ax.set_title("Probability Distribution Function")
title.set_y(1.01)
ax.xaxis.set_major_locator(MaxNLocator(10))
ax.yaxis.set_major_locator(MaxNLocator(10))
ax.zaxis.set_major_locator(MaxNLocator(10))
fig.set_tight_layout(True)
fig.savefig('Gaussian.svg')
The problem is in your arrays. From the documentation to plot_surface:
Axes3D.plot_surface(X, Y, Z, *args, **kwargs)
X, Y, Z: Data values as 2D arrays
your X, Y, Z are 1D arrays, so won't work properly.
You could make x1 and x2 the correct format using np.meshgrid:
x1, x2 = np.meshgrid(x1,x2)
Then generate z using these 2D arrays.
However, note that creating a 10000x10000 surface may use a lot of memory!

Categories