I have a population:
population_men = stats.norm.rvs(loc=19, scale=171, size=11000000) # Sample of men with an average height of 171
population_women = stats.norm.rvs(loc=16, scale=165, size=12000) # A sample of women with an average height of 165
t, p = stats.ttest_ind(population_men, population_women)
t, p
result: (-0.1213798367777649, 0.9033901889229905)
Then I build a graph
plt.hist(population_men, bins=25, color = 'purple'); # Sample A
plt.hist(population_women, bins=25, color = 'blue'); # Sample B
Result:enter image description here
I need to make both samples visible on the graph, as if layered on top of each other.
You can add an alpha param to plt.hist()
Try:
plt.hist(population_men, bins=25, color = 'purple', alpha=0.5, density=True);
plt.hist(population_women, bins=25, color = 'blue', alpha=0.5, density=True);
The size in your stats.norm.rvs() is vastly different so you will only see the stats for population_men. You can fix this by making the 'size' in both variables similar or by using density=True to the normalize them.
Related
first graph
second graph
I tried this script :
X = np.arange( 0, 100)
Quantum_cost_np_q_time = result_df_Quantum_cost['Quantum Cost Execution Time (in s)'].to_numpy()
classical_cost_np_q_time = result_df_classical_cost['Classical Cost Execution Time (in s)'].to_numpy()
plt.plot(X, Quantum_cost_np_q_time, color = 'red', label = 'Quantum_cost_time' )
plt.plot(X, classical_cost_np_q_time, color = "green", label = 'classical_cost_time' )
plt.xlabel("index")
plt.ylabel("execution time")
plt.title("cost")
# Adding legend, which helps us recognize the curve according to it's color
plt.legend()
# To load the display window
plt.show()
I want one graph to compare the two graphs :)
I'm trying to plot contourf of 7 clusters with min value in array of 0 and max of 6. However, when I plot it, there is an extra step size in the plot (the color pink outlining the brown cluster.Even though the colorbar labeled the pink as 5, it isn't supposed to be there so I'm not sure where it came from since label 5 is for the brown cluster and so on.
enter image description here
plt.clf() #clear figure before
fig=plt.figure(figsize=(10,8))
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=100.0, globe=None))
ax.set_extent([96,105,1,8]) # lon_left, lon_right, lat_below, lat_upper
ax.gridlines(linewidths=0.01, draw_labels=True, alpha= 0.3)
ax.xlocator = mticker.FixedLocator(np.arange(96.,105.,0.5))
ax.ylocator = mticker.FixedLocator(np.arange(1.,8.,0.5))
clevs = np.arange(0,7,1)
cs = ax.contourf(coords[0], coords[1], code_recons[0], vmin=0, vmax=6, cmap="Accent", transform=ccrs.PlateCarree())
ax.coastlines("50m") # avail:110m, 50m, 10m..... '10m' is better resolution than default
cb = plt.colorbar(cs)
n_clusters=7
tick_locs = (np.arange(n_clusters) + 0.5)*(n_clusters-1)/n_clusters
cb.set_ticks(tick_locs)
cb.set_ticklabels(np.arange(n_clusters))
plt.show()
Any help is deeply appreciated.
I believe I am 90% of the way to solving this issue. As can be seen on the attached image, I am trying to create a nested donut chart based on two groups (rem and deep), the values have been plotted to show the proportion (in relation to 100%) a user is achieving. I want to display this in the "apple health ring style", in order for this to be effective, I want to highlight the two "types" (rem and deep) using two different colors. Within the image you can see the DF, the code applied to generate the existing view and the output. To summarize, I want to;
Assign a set color to "rem", and a different one for "deep"
Remove the axis labels and tick marks
Ideally (although I can probably do this), better format the labels (in some way).
Output to image file with black background
import re
# create donut plots
my_dpi=150
plt.figure(figsize=(1500/my_dpi, 900/my_dpi), dpi=my_dpi)
startingRadius = 0.7 + (0.3* (len(Ian_MitchellRD)-1))
for index, row in Ian_MitchellRD.iterrows():
scenario = row["index"]
percentage = row["Ian Mitchell"]
textLabel = scenario + ': ' + percentage+ '%'
print(startingRadius)
percentage = int(re.search(r'\d+', percentage).group())
remainingPie = 100 - percentage
donut_sizes = [remainingPie, percentage]
#colors = ['#FDFEFE','#AED6F1','#5cdb6f','#AED6F1']
plt.title('Proportion of Recommended Sleep Type being Achieved')
plt.text(0.05, startingRadius - 0.20, textLabel, horizontalalignment='left', verticalalignment='center', color='black')
plt.pie(donut_sizes, radius=startingRadius, startangle=90, colors=colors, frame=True,
wedgeprops={"edgecolor": "white", 'linewidth': 2}, )
startingRadius-=0.3
# equal ensures pie chart is drawn as a circle (equal aspect ratio)
plt.axis('equal')
# create circle and place onto pie chart
circle = plt.Circle(xy=(0, 0), radius=0.35, facecolor='white')
plt.gca().add_artist(circle)
plt.show()
See image of what the code current generates:
UPDATE:
I amended the code per the recommendation to look into the example suggested, code is now;
import matplotlib.lines as mlines
fig, ax = plt.subplots()
ax.axis('equal')
width = 0.25
fig.patch.set_facecolor('black')
fig.set_size_inches(10,10)
data_1 = Ian_MitchellRD.iloc[0]['Ian Mitchell']
data_2 = Ian_MitchellRD.iloc[1]['Ian Mitchell']
remainingPie_1 = 100 - data_1
remainingPie_2 = 100 - data_2
donut_sizes_1 = [remainingPie_1, data_1]
donut_sizes_2 = [remainingPie_2, data_2]
pie, _ = ax.pie(donut_sizes_1, radius=1, colors=['black','lightgreen'],startangle=90)
plt.setp( pie, width=width, edgecolor='black')
pie2, _ = ax.pie(donut_sizes_2, radius=1-width,startangle=90, colors=['black','pink'])
plt.setp( pie2, width=width, edgecolor='black')
plt.title("Ian Mitchell - Average % of REM + Deep Sleep vs Recommended", fontfamily='Consolas', size=16, color='white')
#setting up the legend
greenbar= mlines.Line2D([], [], color='lightgreen', marker='s', linestyle='None',
markersize=10, label='REM Sleep')
pinkbar = mlines.Line2D([], [], color='pink', marker='s', linestyle='None',
markersize=10, label='Deep Sleep')
plt.legend(handles=[greenbar, pinkbar],prop={'size': 12}, loc='lower right')
plt.show()
generating the following;
I would really appreciate guidance on adding labels either, directly on the relevant sections of the chart - i.e. the green chart has a label of around 94%, and the pink segment around 55%.
Thanks,
New Version
I have three sets of histogram plot displayed by group. In this setting, I would like to differentiate each group by color.
For example, cubicle - red, hallway - blue, office - green. Any advice?
Here's my current code:
df_mean['mean'].hist(by=df_mean['type'])
Have you tried passing color parameter to hist?
plt.hist(x, color='r')
You can set a color for each histogram after you have created the figure with df.hist(), like in this example:
import numpy as np # v 1.19.2
import pandas as pd # v 1.1.3
import matplotlib.pyplot as plt # v 3.3.2
# Create random dataset
rng = np.random.default_rng(seed=12345) # random number generator
df = pd.DataFrame(dict(area_type = np.repeat(['cubicle', 'hallway', 'office'], [9, 10, 12]),
mean = np.append(rng.uniform(low=100, high=1400, size=9),
rng.exponential(scale=500, size=22))))
# Plot grid of histograms using pandas df.hist (note that df.plot.hist
# does not produce the same result, it seems to ignore the 'by' parameter)
grid = df['mean'].hist(by=df['area_type'])
colors = ['red', 'blue', 'green']
# Loop through axes contained in grid and list of colors
for ax, color in zip(grid.flatten(), colors):
# Loop through rectangle patches representing the histogram contained in ax
for patch in ax.patches:
patch.set_color(color)
# Change size of figure
plt.gcf().set_size_inches(8, 6)
plt.show()
Instead of manually picking colors, you could also pick colors automatically from a chosen colormap (in this case a qualitative colormap is appropriate), like this:
# Select colormap properties
cmap_name = 'Accent' # enter any colormap name (see whole list by running plt.colormaps())
ncolors = df['area_type'].nunique()
# Extract list of colors that span the entire gradient of the colormap
cmap = plt.cm.get_cmap(cmap_name)
colors = cmap(np.linspace(0, 1, ncolors))
# Create plot like in previous example
grid = df['mean'].hist(by=df['area_type'])
for ax, color in zip(grid.flatten(), colors):
for patch in ax.patches:
patch.set_color(color)
plt.gcf().set_size_inches(8, 6)
plt.show()
I'd like to plot a transparent contour plot over an image file in matplotlib/pyplot.
Here's what I got so far...
I have a 600x600 pixel square image file test.png that looks like so:
I would like to plot a contour plot over this image (having the image file be 'below' and a semi-transparent version of the contour plot overlaid) using matplotlib and pyplot. As a bonus, the image would be automatically scaled to fit within the current plotting boundaries. My example plotting script is as follows:
from matplotlib import pyplot
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
from matplotlib.colors import BoundaryNorm
from matplotlib.ticker import MaxNLocator
from pylab import *
import numpy as np
import random
# ----------------------------- #
dx, dy = 500.0, 500.0
y, x = np.mgrid[slice(-2500.0, 2500.0 + dy, dy),slice(-2500.0, 2500.0 + dx, dx)]
z = []
for i in x:
z.append([])
for j in y:
z[-1].append(random.uniform(80.0,100.0))
# ----------------------------- #
plot_aspect = 1.2
plot_height = 10.0
plot_width = int(plot_height*plot_aspect)
# ----------------------------- #
pyplot.figure(figsize=(plot_width, plot_height), dpi=100)
pyplot.subplots_adjust(left=0.10, right=1.00, top=0.90, bottom=0.06, hspace=0.30)
subplot1 = pyplot.subplot(111)
# ----------------------------- #
cbar_max = 100.0
cbar_min = 80.0
cbar_step = 1.0
cbar_num_colors = 200
cbar_num_format = "%d"
# ----------
levels = MaxNLocator(nbins=cbar_num_colors).tick_values(cbar_min, cbar_max)
cmap = pyplot.get_cmap('jet')
norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)
pp = pyplot.contourf(x,y,z,levels=levels,cmap=cmap)
cbar = pyplot.colorbar(pp, orientation='vertical', ticks=np.arange(cbar_min, cbar_max+cbar_step, cbar_step), format=cbar_num_format)
cbar.ax.set_ylabel('Color Scale [unit]', fontsize = 16, weight="bold")
# ----------
CS = pyplot.contour(x,y,z, alpha=0.5)
# ----------
majorLocator1 = MultipleLocator(500)
majorFormatter1 = FormatStrFormatter('%d')
minorLocator1 = MultipleLocator(250)
subplot1.xaxis.set_major_locator(majorLocator1)
subplot1.xaxis.set_major_formatter(majorFormatter1)
subplot1.xaxis.set_minor_locator(minorLocator1)
pyplot.xticks(fontsize = 16)
pyplot.xlim(-2500.0,2500.0)
# ----------
majorLocator2 = MultipleLocator(500)
majorFormatter2 = FormatStrFormatter('%d')
minorLocator2 = MultipleLocator(250)
subplot1.yaxis.set_major_locator(majorLocator2)
subplot1.yaxis.set_major_formatter(majorFormatter2)
subplot1.yaxis.set_minor_locator(minorLocator2)
pyplot.yticks(fontsize = 16)
pyplot.ylim(-2500.0,2500.0)
# ----------
subplot1.xaxis.grid()
subplot1.yaxis.grid()
# ----------
subplot1.axes.set_aspect('equal')
# ----------
pyplot.suptitle('Main Title', fontsize = 24, weight="bold")
# ----------
pyplot.xlabel('X [m]', fontsize=16, weight="bold")
pyplot.ylabel('Y [m]', fontsize=16, weight="bold")
# ----------
implot = subplot1.imshow( pyplot.imread('test.png') , interpolation='nearest', alpha=0.5)
# ----------
pyplot.show()
#pyplot.savefig("tmp.png", dpi=100)
pyplot.close()
...but I'm not getting the result I want... instead I just see the contour plot part. Something like:
What should I do in my code to get what I want?
You basically need to do two things, set the extent of the image you want in the background. If you dont, the coordinates are assumed to be pixel coordinates, in this case 0 till 600 for both x and y. So adjust you imshow command to:
implot = subplot1.imshow(pyplot.imread(r'test.png'), interpolation='nearest',
alpha=0.5, extent=[-2500.0,2500.0,-2500.0,2500.0])
If you want to stretch the image to the limits of the plot automatically, you can grab the extent with:
extent = subplot1.get_xlim()+ subplot1.get_ylim()
And pass it to imshow as extent=extent.
Since its the background image, setting the alpha to 0.5 makes it very faint, i would set it to 1.0.
Secondly, you set the alpha of the contour lines, but you probably also (or especially) want to set the alpha of the filled contours. And when you use alpha with filled contours, enabling anti-aliasing reduces artifacts. So change your contourf command to:
pp = pyplot.contourf(x,y,z,levels=levels,cmap=cmap, alpha=.5, antialiased=True)
And since you already create the subplot object yourself, i would advice also using it to do the plotting instead of the pyplot interface, which operates on the currently active axes.
So:
subplot1.contourf()
etc
Instead of:
pyplot.contourf()
With the two changes mentioned above, my result looks like:
I personally used the multiple contour plot answer for a while with great results. However, I had to output my figures to PostScript, which does not support opacity (alpha option). I found this answer useful since it does not require the use of opacity.
The reason these lines show up is due to the edge color of the faces that make up the contour plot. The linked solution avoids this by changing the edge color to the face color.
cf = plt.contourf(x, y, z, levels=100)
# This is the fix for the white lines between contour levels
for c in cf.collections:
c.set_edgecolor("face")