I'm trying to reproduce the following chart:
But I'm not sure if's actually possible to create such a plot using Python,R or Tableau.
Here is my first attempt using Plotly in R:
Do you have any suggestion for creating such a chart?
You can use R and de package highcharter to create a plot like this one:
spiderweb plot
the plot js code is in www/highcharts.com/demo/polar-spider
While I was working on creating this plot with matplotlib, someone mentioned that I can create this chart using Excel! in less than 2 minutes, so I didn't complete the code but anyway as I already figure out how should I create different elements of the plot in matplotlib, I put the code here in case anyone wants to create such a thing.
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig1 = plt.figure()
#Adding grids
for rad in reversed(range(1,10)): #10 is maximum of ranks we need to show
ax1 = fig1.add_subplot(111,aspect = 'equal')
ax1.add_patch(
patches.RegularPolygon(
(0,0), #center of the shape
11, #number of vertices
rad,
fill=False,
ls='--',
))
plt.xlim(xmin = -10,xmax=10)
plt.ylim(ymin = -10,ymax=10)
fig1.show()
#plotting the trend
plt.scatter(xs,ys) #xs = list of x coordinates, the same for ys
for k in range(len(xs)-1):
x, y = [xs[k], xs[k+1]], [ys[k], ys[k+1]]
plt.plot(x, y,color = 'b')
plt.grid(False)
plt.show()
Result plot
(As I said the code doesn't create the whole trends, labels,...but it's pretty much all you need to create the plot)
Related
So, what I am having trouble with is how I am supposed to plot the data I have on top of a global map. I have an array of data, and two arrays of coordinates in latitude and longitude, where each datapoint was taken, but I am not sure of how to plot it on top of a global map. Creating the map itself is not too difficult, I just use:
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
fig = plt.figure(figsize=(10, 8))
m = Basemap(projection='cyl', resolution='c',
llcrnrlat=-90, urcrnrlat=90,
llcrnrlon=-180, urcrnrlon=180, )
m.shadedrelief(scale=0.5)
m.drawcoastlines(color='black')
But the next step is where I am having problems. I have tried doing both a colormesh plot and scatter plot, but they haven't worked so far. How should I go about it so that the data is plotted in the correct coordinate locations for the global map?
Thanks a lot for any help!
Maybe a bit late, but I have this piece of code I used to plot multiple linear plot over a map in Basemap that worked for me.
map = Basemap(projection='cyl', resolution='c',
llcrnrlat=mins[1], urcrnrlat=maxs[1],
llcrnrlon=mins[0], urcrnrlon=50, )
plt.figure(figsize=(15, 15))
for i in range(1259):
filepath = filename[i]
data = pd.read_csv(filepath, index_col=0)
map.plot(data.x,data.y,'k-', alpha=0.1) ### Calling the plot in a loop!!
map.drawcoastlines(linewidth=1)
map.drawcountries(linewidth=0.5, linestyle='solid', color='k' )
plt.show()
The loop calls data from different folders, and I just use the map.plot command to plot. By doing it like that, you can plot all data in the same map.
I'm pretty new to Python. I'm trying to plot a box plot for a sample data
I'm trying to plot box plots of mean value of the shared data. I got that part of the code. I'm also trying to plot standard error values on this box plot using yerr().
My code:
data3=pd.read_csv('demo1.csv')
names=['brow', 'harr', 'hage', 'buch', 'mcre']
d=[data3['brow'].mean(),data3['harr'].mean(),data3['hage'].mean(),data3['buch'].mean(),data3['mcre'].mean()]
N=len(data3['co'])
l=math.sqrt(N)
k=[(data3['brow'].std())/l,(data3['harr'].std())/l,(data3['hage'].std())/l,(data3['buch'].std())/l,(data3['mcre'].std())/l,(data3['phil'].std())/l,(data3['moor'].std())/l]
fig, ax = plt.subplots()
plt.bar(names,d)
plt.bar(len(names),d,yerr=k,align='center',alpha=0.5,ecolor='black',capsize=10)
Im getting an image such as this
But I want the black lines to be against each bar graph and not as a new bar in the plot with all of them together. How can I change this. Am I using the plt the wrong way? Please help.
I don't understand what you were trying to do with your second call to plt.bar()
import math
names=['brow', 'harr', 'hage', 'buch', 'mcre']
data3 = pd.DataFrame({n: np.random.normal(loc=np.random.randint(5,10), scale=np.random.randint(1,10), size=(100,)) for n in names})
d=data3[names].mean()
N=100
l=math.sqrt(N)
k=data3[names].std()/l
fig, ax = plt.subplots()
plt.bar(names,d,yerr=k,align='center',alpha=0.5,ecolor='black',capsize=10)
I want to draw Grid of Bar graph/Histogram for my data.My Data contains 1 NUMERIC and 3 CATEGORICAL Column
PAIRGraph is not suitable for my purpose as my purpose as I have only 1 Numeric and 3 Categorical Column
Tried to Refer Documentation https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots.html
However, I am unable to find exact way to fulfill my requirement.
Using Demo code I am able to draw only LineGraph. However, I am required to draw Bar Graph.
fig, axes = plt.subplots(1, 2, figsize=(10,4))
x = np.linspace(0, 5, 11)
axes[0].plot(x, x**2, x, np.exp(x),x,20*x)
axes[0].set_title("Normal scale")
axes[0].plot
axes[1].plot(x, x**2, x, np.exp(x))
axes[1].set_yscale("log")
axes[1].set_title("Logarithmic scale (y)");
Please feel free to correct my approach or guide me as I have just started learning.
If you specify exactly what you want to use for the bar and hist, I can modify, but generally it is simply changing the plot to the type of chart you need
import matplotlib.pyplot as plt
import numpy as np
fig, axes = plt.subplots(1, 2, figsize=(10,4))
x = np.linspace(0, 5, 11)
axes[0].bar(x,x**2) # bar plot
axes[0].set_title("Normal scale")
axes[0].plot
axes[1].hist(x) # histogram
axes[1].set_yscale("log")
axes[1].set_title("Logarithmic scale (y)");
plt.show()
After going through the API documentation from Matplotlip Subplot Axes, I found ways to draw different graph not just Line graph.
https://matplotlib.org/api/axes_api.html
DEFAULT:-
axes[0].plot by-default draws line graph.
CUSTOM GRAPH:-
axes[0].bar can be used to draw BAR graph in selected Subplot
axes[0].scatter can be used to draw Scatter graph in selected Subplot
axes[0].hist can be used to draw a histogram. in selected Subplot
Like above example more graph can be drawn with below API:-
I would like to make beautiful scatter plots with histograms above and right of the scatter plot, as it is possible in seaborn with jointplot:
I am looking for suggestions on how to achieve this. In fact I am having some troubles in installing pandas, and also I do not need the entire seaborn module
I encountered the same problem today. Additionally I wanted a CDF for the marginals.
Code:
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
x = np.random.beta(2,5,size=int(1e4))
y = np.random.randn(int(1e4))
fig = plt.figure(figsize=(8,8))
gs = gridspec.GridSpec(3, 3)
ax_main = plt.subplot(gs[1:3, :2])
ax_xDist = plt.subplot(gs[0, :2],sharex=ax_main)
ax_yDist = plt.subplot(gs[1:3, 2],sharey=ax_main)
ax_main.scatter(x,y,marker='.')
ax_main.set(xlabel="x data", ylabel="y data")
ax_xDist.hist(x,bins=100,align='mid')
ax_xDist.set(ylabel='count')
ax_xCumDist = ax_xDist.twinx()
ax_xCumDist.hist(x,bins=100,cumulative=True,histtype='step',density=True,color='r',align='mid')
ax_xCumDist.tick_params('y', colors='r')
ax_xCumDist.set_ylabel('cumulative',color='r')
ax_yDist.hist(y,bins=100,orientation='horizontal',align='mid')
ax_yDist.set(xlabel='count')
ax_yCumDist = ax_yDist.twiny()
ax_yCumDist.hist(y,bins=100,cumulative=True,histtype='step',density=True,color='r',align='mid',orientation='horizontal')
ax_yCumDist.tick_params('x', colors='r')
ax_yCumDist.set_xlabel('cumulative',color='r')
plt.show()
Hope it helps the next person searching for scatter-plot with marginal distribution.
Here's an example of how to do it, using gridspec.GridSpec:
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
import numpy as np
x = np.random.rand(50)
y = np.random.rand(50)
fig = plt.figure()
gs = GridSpec(4,4)
ax_joint = fig.add_subplot(gs[1:4,0:3])
ax_marg_x = fig.add_subplot(gs[0,0:3])
ax_marg_y = fig.add_subplot(gs[1:4,3])
ax_joint.scatter(x,y)
ax_marg_x.hist(x)
ax_marg_y.hist(y,orientation="horizontal")
# Turn off tick labels on marginals
plt.setp(ax_marg_x.get_xticklabels(), visible=False)
plt.setp(ax_marg_y.get_yticklabels(), visible=False)
# Set labels on joint
ax_joint.set_xlabel('Joint x label')
ax_joint.set_ylabel('Joint y label')
# Set labels on marginals
ax_marg_y.set_xlabel('Marginal x label')
ax_marg_x.set_ylabel('Marginal y label')
plt.show()
I strongly recommend to flip the right histogram by adding these 3 lines of code to the current best answer before plt.show() :
ax_yDist.invert_xaxis()
ax_yDist.yaxis.tick_right()
ax_yCumDist.invert_xaxis()
The advantage is that any person who is visualizing it can compare easily the two histograms just by moving and rotating clockwise the right histogram on their mind.
On contrast, in the plot of the question and in all other answers, if you want to compare the two histograms, your first reaction is to rotate the right histogram counterclockwise, which leads to wrong conclusions because the y axis gets inverted. Indeed, the right CDF of the current best answer looks decreasing at first sight:
I have a small issue with matplotlib.pyplot and I hope someone might have come across it before.
I have data that contain X,Y,e values that are the X, Y measurements of a variable and e are the errors of the measurements in Y. I need to plot them in a log log scale.
I use the plt.errorbars function to plot them and then set yscale and xscale to log and this works fine. But I need to also plot a line on the same graph that needs to be in linear scale.
I am able to have the plots done separately just fine but I would like to have them in the same image if possible. Do you have any ideas? I am posting what I have done for now.
Cheers,
Kimon
tdlist = np.array([0.01,0.02,0.05,0.1,0.2,0.3,0.4,0.5,0.8,1,2,5,10,15,20,25,30,40,60,80,100,150,200,250,300,400])
freqlist=np.array([30,40,50,60,70,80,90,100,110,120,140,160,180,200,220,250,300,350,400,450])
filename=opts.filename
data = reader(filename)
data2 = logconv(data)
#x,y,e the data. Calculating usefull sums
x = data2[0]
y = data2[1]
e = data2[2]
xoe2 = np.sum(x/e**2)
yoe2 = np.sum(y/e**2)
xyoe2 = np.sum(x*y/e**2)
oe2 = np.sum(1/e**2)
x2oe2 = np.sum(x**2/e**2)
aslope = (xoe2*yoe2-xyoe2*oe2)/(xoe2**2-x2oe2*oe2)
binter = (xyoe2-aslope*x2oe2)/xoe2
aerr = np.sqrt(oe2/(x2oe2*oe2-xoe2**2))
berr = np.sqrt(x2oe2/(x2oe2*oe2-xoe2**2))
print('slope is ',aslope,' +- ', aerr)
print('inter is ',binter,' +- ', berr)
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax2 = fig.add_axes(ax1.get_position(), frameon=False)
ax1.errorbar(data[0],data[1],yerr=data[2],fmt='o')
ax1.set_xscale('log',basex=10)
ax1.set_yscale('log',basey=10)
ax1.set_yticks([])
ax1.set_xticks([])
ax2.plot(x,aslope*x+binter,'r')
ax2.plot(x,(aslope-aerr)*x+(binter+berr),'--')
ax2.plot(x,(aslope+aerr)*x+(binter-berr),'--')
ax2.set_xscale('linear')
ax2.set_yscale('linear')
plt.xticks(np.log10(freqlist),freqlist.astype('int'))
plt.yticks(np.log10(tdlist),tdlist.astype('float'))
plt.xlabel('Frequency (MHz)')
plt.ylabel('t_s (msec)')
fitndx1 = 'Fit slope '+"{0:.2f}".format(aslope)+u"\u00B1"+"{0:.2f}".format(aerr)
plt.legend(('Data',fitndx1))
plt.show()
Following Molly's suggestion I managed to get closer to my goal but still not there. I am adding a bit more info for what I am trying to do and it might clarify things a bit.
I am setting ax1 to the errobar plot that uses loglog scale. I need to use errorbar and not loglog plot so that I can display the errors with my points.
I am using ax2 to plot the linear fit in linealinear scale.
Moreover I do not want the x and y axes to display values that are 10,100,1000 powers of ten but my own axes labels that have the spacing I want therefore I am using the plt.xticks. I tried ax1.set_yticks and ax1.set_yticklabes but with no success. Below is the image I am getting.
I do not have enough reputation to post an image but here is the link of it uploaded
http://postimg.org/image/uojanigab/
The values of my points should be x range = 40 - 80 and y range = 5 -200 as the fit lines are now.
You can create two overlapping axes using the add_suplot method of figure. Here's an example:
from matplotlib import pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax2 = fig.add_axes(ax1.get_position(), frameon=False)
ax1.loglog([1,10,100,1000],[1000,1,100,10])
ax2.plot([5,10,11,13],'r')
plt.show()
You can then turn off the x and y ticks for the linear scale plot like this:
ax2.set_xticks([])
ax2.set_yticks([])
I was not able to get two sets of axis working with the errorbar function so I had to convert everything to log scale including my linear plot. Below is the code I use to get it might be useful to someone.
plt.errorbar(data[0],data[1],yerr=data[2],fmt='o')
plt.xscale('log',basex=10)
plt.yscale('log',basey=10)
plt.plot(data[0],data[0]**aslope*10**binter,'r')
plt.plot(data[0],data[0]**(aslope-aerr)*10**(binter+berr),'--')
plt.plot(data[0],data[0]**(aslope+aerr)*10**(binter-berr),'--')
plt.xticks(freqlist,freqlist.astype('int'))
plt.yticks(tdlist,tdlist.astype('float'))
plt.xlabel('Frequency (MHz)')
plt.ylabel('t_s (msec)')
fitndx1 = 'Fit slope '+"{0:.2f}".format(aslope)+u"\u00B1"+"{0:.2f}".format(aerr)
plt.legend(('Data',fitndx1))
plt.show()
And here is the link to the final image
http://postimg.org/image/bevj2k6nf/