I seek help in editing my plot. Here in the image you can see I am getting vertical lines in all the six plots.
But I want a smooth curve.
Here is my code what I have tried so far
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
from math import *
from scipy.stats import skew
from scipy.interpolate import make_interp_spline
import scipy
import seaborn as sns
plt.rcParams["figure.figsize"] = (12,3)
df=pd.read_csv("plot_data00.txt")
df=df[df['DOY'].between(184,187)]
df["HR"] = df["HR"]/24
df["DOY"] = df["DOY"]+ df["HR"]
df.to_csv("final_plot_data.txt")
#define variables to plot
import matplotlib.pyplot as plt
fig,axes= plt.subplots(nrows=6, ncols=1, squeeze=False)
x = df["DOY"]
y = df["By"]
z = df["Bz"]
a = df["Vsw"]
b = df["Nsw"]
c = df["reconnection_rate"]
d = df["magnetopause_distance"]
#create a figure and edit size
fig=plt.figure(figsize=(20,17))
#define subplots and define their position
plt1=fig.add_subplot(611)
plt2=fig.add_subplot(612)
plt3=fig.add_subplot(613)
plt4=fig.add_subplot(614)
plt5=fig.add_subplot(615)
plt6=fig.add_subplot(616)
plt1.plot("DOY", "By", data=df)
plt1.set_ylabel("By",size=16)
plt1.set_title("3-6 July 2003",size=20)
plt1.get_yaxis().set_label_coords(-0.05,0.5)
plt2.plot("DOY", "Bz", data=df)
plt2.set_ylabel("Bz",size=16)
plt2.get_yaxis().set_label_coords(-0.05,0.5)
plt3.plot("DOY", "Vsw", data=df)
plt3.set_ylabel("Vsw",size=16)
plt3.get_yaxis().set_label_coords(-0.05,0.5)
plt4.plot("DOY", "Nsw", data=df)
plt4.set_ylabel("Nsw",size=16)
plt4.get_yaxis().set_label_coords(-0.05,0.5)
plt5.plot("DOY", "reconnection_rate", data=df)
plt5.set_ylabel("MRR",size=16)
plt5.get_yaxis().set_label_coords(-0.05,0.5)
plt6.plot("DOY", "magnetopause_distance", data=df)
plt6.set_ylabel("MD",size=16)
plt6.set_xlabel("Day of Year",size=16)
plt6.get_yaxis().set_label_coords(-0.05,0.5)
#plt.subplots_adjust(hspace = ,wspace = 5)
#saving plot in .jpg format
plt.savefig('myplot03.jpg', format='jpeg',dpi=None, edgecolor='g', transparent=True, bbox_inches='tight')
I could have add my data, but no option seems better to represent it, a it is large(Suggestions are invited).
Thankyou for your time.
UPDATE:
The sample data for use is:
,Unnamed: 0,Unnamed: 0.1,index,YYYY,DOY,HR,MN,By,Bz,Vsw,Nsw,reconnection_rate,magnetopause_distance
0,225369,225369,263522,2003,184.0,0.0,2,4990000000.0,670000000.0,0.5928000000000002,1.49e-06,12573.256929898798,10.858269653698725
1,225370,225370,263523,2003,184.0,0.0,3,4080000000.0,390000000.0000001,0.5825,1.47e-06,11009.972803627901,10.946523155327649
2,225371,225371,263524,2003,184.0,0.0,4,4300000000.000002,-110000000.0,0.5675,1.4499999999999999e-06,13184.030740514894,11.067370358771116
1420,226789,226789,265056,2003,185.04340277777774,0.0017361111111111108,36,1100000000.0,4550000000.0,0.6971,4.589999999999999e-06,6.417619779966155,8.528263110991979
1421,226790,226790,265057,2003,185.04340277777774,0.0017361111111111108,37,530000000.0,6020000000.0,0.7007000000000001,4.17e-06,0.09620386453014222,8.650894534287474
1422,226791,226791,265058,2003,185.04340277777774,0.0017361111111111108,38,-3110000000.0,6230000000.000001,0.6958000000000002,4.779999999999998e-06,187.4614444320996,8.476077939976314
2765,228134,228134,266471,2003,186.04340277777774,0.0017361111111111108,11,3510000000.0000005,-2500000000.0,0.7323999999999999,1.7399999999999999e-06,2791.603594666996,9.860980027267642
2766,228135,228135,266472,2003,186.04340277777774,0.0017361111111111108,12,2000000000.0,-4340000000.000002,0.7396,1.42e-06,102.51414877271608,10.167496717459473
4048,229417,229417,267898,2003,187.0,0.0,58,5280000000.000001,1240000000.0,0.6935,1.22e-06,12837.913793204994,10.654153236043083
4049,229418,229418,267899,2003,187.0,0.0,59,3470000000.0,3690000000.0,0.6901,1.24e-06,1136.6725720724482,10.642739751911767
Sorry it looks clumsy, but it will help you to understand what i want to do actually.
Use scipy.interpolate module:
Plot raw data
sr = df.set_index('DOY')['Bz']
x = sr.index.values
y = sr.values
tck, u = interpolate.splprep([x, y])
u = np.linspace(0, 1, num=100, endpoint=True)
out = interpolate.splev(u, tck)
plt.plot(x, y, 'b', out[0], out[1], 'r')
plt.show()
Plot using the mean for same DOY
sr = df.set_index('DOY')['Bz'].groupby('DOY').mean()
x = sr.index.values
y = sr.values
tck, u = interpolate.splprep([x, y])
u = np.linspace(0, 1, num=100, endpoint=True)
out = interpolate.splev(u, tck)
plt.plot(x, y, 'b', out[0], out[1], 'r')
plt.show()
Combined
sr = df.set_index('DOY')['Bz']
x = sr.index.values
y = sr.values
sr2 = sr.groupby(level=0).mean()
x2 = sr2.index.values
y2 = sr2.values
tck, u = interpolate.splprep([x2, y2])
u = np.linspace(0, 1, num=100, endpoint=True)
out = interpolate.splev(u, tck)
plt.plot(x, y, 'b', out[0], out[1], 'r')
plt.show()
from mplsoccer.pitch import Pitch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde
np.random.seed(19680801)
plt.style.use('dark_background')
fields = ['id', 'minute', 'result', 'X1', 'Y','xG','h_a','situation','season',
'shotType','X']
df=pd.read_csv('shots.csv', skipinitialspace=True, usecols=fields)
df1 = pd.DataFrame({'A':df.Y,'B':df.X} )
a=(df1.to_numpy())
x, y = a.T
k = kde.gaussian_kde(a.T)
nbins=50
xi, yi = np.mgrid[x.min():x.max():nbins*1j, y.min():y.max():nbins*1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))
pitch = Pitch(orientation='vertical',pitch_type='metricasports', view='half',
linewidth=2, line_zorder=1,
line_color= '#94A7AE',pitch_length=105, pitch_width=68,pad_bottom=0)
fig, ax = pitch.draw()
ax.pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud', cmap='Reds',facecolor='black'
)
ax.set_xlim(ax.get_xlim()[::-1])
ax.yaxis.tick_right()
plt.axis('off')
plt.show()
Output Plot here
I want the only red-colored density plot, not the white rectangular background frame. How to make the frame the same as my background?
Here is an approach using a colormap with an "under" color of 'none'. By setting vmin to a cut-off value, the cells with a lower value will get the "under" color ('none' stands for fully transparent). To get an idea of the values, temporarily a colorbar can be added. The values depend strongly on the extension of the x and y values (the integral of the kde is 1, so over a small domain the values need to be high enough).
from mplsoccer.pitch import Pitch
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde
from copy import copy
np.random.seed(19680801)
plt.style.use('dark_background')
# first create some random toy data roughly mimicking the given plot
x = np.random.randn(100, 20).cumsum(axis=0).flatten()
y = np.random.randn(100, 20).cumsum(axis=0).flatten()
x = x * 0.04 + 0.5
y = y * 0.01 + 0.9
k = kde.gaussian_kde([x, y])
nbins = 50
xi, yi = np.mgrid[x.min():x.max():nbins * 1j, y.min():y.max():nbins * 1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))
pitch = Pitch(orientation='vertical', pitch_type='metricasports', view='half',
linewidth=2, line_zorder=1,
line_color='#94A7AE', pitch_length=105, pitch_width=68, pad_bottom=0)
fig, ax = pitch.draw()
cmap = copy(plt.get_cmap('Reds'))
cmap.set_under('none')
pmesh = ax.pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud', cmap=cmap, vmin=5, facecolor='black')
# fig.colorbar(pmesh, ax=ax) # to temporarily get an idea of the values
ax.invert_xaxis()
ax.yaxis.tick_right()
plt.axis('off')
plt.show()
I have n_series recordings with the same frames 0, 1, 2, 3,... and would like to make a 2D contour out of it.
I've found that I can very easily do the following:
import matplotlib.pyplot as plt
import numpy as np
series_len = 1000
n_series = 10
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xbins, ybins = np.histogram2d(x, y, bins=20)
plt.contourf(heatmap.T)
plt.show()
But since this just gives a 20x20 histogram, I have no idea how my intensities are distributed in the outputted plot (e.g. roughly zero-centered), nor how to fix the ticks.
What I'd like is this ('shopped):
Try set_xticklabels:
series_len = 1000
n_series = 10
fig, ax = plt.subplots(figsize=(10,6))
np.random.seed(1)
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xs, ys = np.histogram2d(x, y, bins=20)
fig, ax = plt.subplots(figsize=(10,6))
ax.contourf(heatmap.T)
# the actual x-axis and y-axis are from 0 to 19
# we want to put 11 ticks on the axis
ax.set_xticks(np.linspace(0,19,11))
ax.set_xticklabels(range(0,1001,100))
ax.set_yticks(np.linspace(0,19,11))
ax.set_yticklabels(['{:.3f}'.format(y) for y in ys[::2]])
plt.show()
Output:
IIUC, did you want something like this:
import matplotlib.pyplot as plt
import numpy as np
series_len = 1000
n_series = 10
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xlabels, ylabels = np.histogram2d(x, y, bins=20)
plt.contourf(xlabels[:-1], ylabels[:-1], heatmap.T)
plt.colorbar()
plt.show()
Output:
Okay, found an answer myself which makes the process much simpler than it appears to be. Simply resize the heatmap by 1 in both directions using skimage will make everything follow along nicely.
import matplotlib.pyplot as plt
import numpy as np
import skimage.transform
series_len = 1000
n_series = 10
bins = 20
y = np.random.normal(0, 0.15, series_len * n_series)
x = np.tile(np.arange(0, series_len, 1), n_series)
heatmap, xlabels, ylabels = np.histogram2d(x, y, bins=bins)
heatmap = skimage.transform.resize(heatmap, output_shape = (bins+1, bins+1), mode = "symmetric")
plt.contourf(xlabels, ylabels, heatmap.T)
plt.xlim(0, 1000)
plt.ylim(-0.5, 0.5)
plt.show()
here is the code im using and I've also attached the output. I'd like to plot a two dimensional lognorm function as a 3d surface, the above code is supposed to do this however the output results in the entire plane being skewed rather than just the z values. any help or suggestions would be greatly appreciated.
dx = 90 - (-90)
dy = 90 - (-90)
c = [dx + dx/2.0, dy+dy/2.0]
z = np.zeros((400, 400))
x = np.linspace(-90, 90, 400)
y = x.copy()
for i in range(len(x)):
for j in range(len(y)):
p =[x[i], y[j]]
d = math.sqrt((p[0]-c[0])**2 + (p[1]-c[1])**2)
t = d
z[i][j] = lognorm.pdf(t, 1.2)
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.plot_surface(x,y, z, cmap = 'viridis')
plt.show()
output of the provided code
ideally I'd like for it to look something like this.
this is the image here
I think you wanted to plot a 3D surface and here is an example:
#!/usr/bin/python3
# 2018/10/25 14:44 (+0800)
# Plot a 3D surface
from scipy.stats import norm, lognorm
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
xy = np.linspace(-5, 5, 400)
xx, yy = np.meshgrid(xy)
t = np.sqrt(xx**2 + yy**2)
zz = lognorm.pdf(t, 1.2)
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.plot_surface(xx,yy, zz, cmap = 'viridis')
plt.show()
I have the following (example) code:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
n_lines = 5
x = np.linspace(0, 10, 100)
y = np.sin(x[:, None] + np.pi * np.linspace(0, 1, n_lines))
c = np.arange(1, n_lines + 1)
norm = mpl.colors.Normalize(vmin=c.min(), vmax=c.max())
cmap = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.jet)
cmap.set_array([])
fig, ax = plt.subplots(dpi=100)
for i, yi in enumerate(y.T):
ax.plot(x, yi, c=cmap.to_rgba(i + 1))
fig.colorbar(cmap, ticks=c)
plt.show();
I would like to find a substirute for cmap.to_rgba that makes the colour of each line come out as a differnet shade of blue. Basically I want to keep the same layout as the result of this code, but using the colour map Blues.
How can I do it?
You need to change your colormap that you are using from jet to Blues.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
n_lines = 5
x = np.linspace(0, 10, 100)
y = np.sin(x[:, None] + np.pi * np.linspace(0, 1, n_lines))
c = np.arange(1, n_lines + 1)
norm = mpl.colors.Normalize(vmin=c.min(), vmax=c.max())
cmap = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.Blues)
cmap.set_array([])
fig, ax = plt.subplots(dpi=100)
for i, yi in enumerate(y.T):
ax.plot(x, yi, c=cmap.to_rgba(i + 1))
fig.colorbar(cmap, ticks=c)
plt.show()
This produces: