I have 2 dataframes. I want to plot a histogram based on a column 'rate' for each, side by side. How to do it?
I tried this:
import matplotlib.pyplot as plt
plt.subplot(1,2,1)
dflux.hist('rate' , bins=100)
plt.subplot(1,2,2)
dflux2.hist('rate' , bins=100)
plt.tight_layout()
plt.show()
It did not have the desired effect. It showed two blank charts then one populated chart.
Use subplots to define a figure with two axes. Then specify the axis to plot to within hist using the ax parameter.
fig, axes = plt.subplots(1, 2)
dflux.hist('rate', bins=100, ax=axes[0])
dflux2.hist('rate', bins=100, ax=axes[1])
Demo
dflux = pd.DataFrame(dict(rate=np.random.randn(10000)))
dflux2 = pd.DataFrame(dict(rate=np.random.randn(10000)))
fig, axes = plt.subplots(1, 2)
dflux.hist('rate', bins=100, ax=axes[0])
dflux2.hist('rate', bins=100, ax=axes[1])
Related
This question already has answers here:
Annotate bars with values on Pandas bar plots
(4 answers)
Closed 1 year ago.
I would like to create an annotation to a bar chart that compares the value of the bar to two reference values. An overlay such as shown in the picture, a kind of staff gauge, is possible, but I'm open to more elegant solutions.
The bar chart is generated with the pandas API to matplotlib (e.g. data.plot(kind="bar")), so a plus would be if the solution is playing nicely with that.
You may use smaller bars for the target and benchmark indicators. Pandas cannot annotate bars automatically, but you can simply loop over the values and use matplotlib's pyplot.annotate instead.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
a = np.random.randint(5,15, size=5)
t = (a+np.random.normal(size=len(a))*2).round(2)
b = (a+np.random.normal(size=len(a))*2).round(2)
df = pd.DataFrame({"a":a, "t":t, "b":b})
fig, ax = plt.subplots()
df["a"].plot(kind='bar', ax=ax, legend=True)
df["b"].plot(kind='bar', position=0., width=0.1, color="lightblue",legend=True, ax=ax)
df["t"].plot(kind='bar', position=1., width=0.1, color="purple", legend=True, ax=ax)
for i, rows in df.iterrows():
plt.annotate(rows["a"], xy=(i, rows["a"]), rotation=0, color="C0")
plt.annotate(rows["b"], xy=(i+0.1, rows["b"]), color="lightblue", rotation=+20, ha="left")
plt.annotate(rows["t"], xy=(i-0.1, rows["t"]), color="purple", rotation=-20, ha="right")
ax.set_xlim(-1,len(df))
plt.show()
There's no direct way to annotate a bar plot (as far as I am aware) Some time ago I needed to annotate one so I wrote this, perhaps you can adapt it to your needs.
import matplotlib.pyplot as plt
import numpy as np
ax = plt.subplot(111)
ax.set_xlim(-0.2, 3.2)
ax.grid(b=True, which='major', color='k', linestyle=':', lw=.5, zorder=1)
# x,y data
x = np.arange(4)
y = np.array([5, 12, 3, 7])
# Define upper y limit leaving space for the text above the bars.
up = max(y) * .03
ax.set_ylim(0, max(y) + 3 * up)
ax.bar(x, y, align='center', width=0.2, color='g', zorder=4)
# Add text to bars
for xi, yi, l in zip(*[x, y, list(map(str, y))]):
ax.text(xi - len(l) * .02, yi + up, l,
bbox=dict(facecolor='w', edgecolor='w', alpha=.5))
ax.set_xticks(x)
ax.set_xticklabels(['text1', 'text2', 'text3', 'text4'])
ax.tick_params(axis='x', which='major', labelsize=12)
plt.show()
I've two plots generated using matplotlib. The first represents my backround and the second a group of points which I want to show. Is there a way to overlap the two plots?
background:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize = (10,10))
grid_duomo = gpd.read_file('/content/Griglia_2m-SS.shp')
grid_duomo.to_crs(epsg=32632).plot(ax=ax, color='lightgrey')
points:
fig = plt.figure(figsize=(10, 10))
ids = traj_collection_df_new_app['id'].unique()
for id_ in ids:
self_id = traj_collection_df_new_app[traj_collection_df_new_app['id'] == id_]
plt.plot(
self_id['lon'],
self_id['lat'],
# markers= 'o',
# markersize=12
)
plt.plot() will always take the most recent axis found by matplotlib and use it for plotting.
Its practically the same as plt.gca().plot() where plt.gca() stands for "get current axis".
To get full control over which axis is used, you should do something like this:
(the zorder argument is used to set the "vertical stacking" of the artists, e.g. zorder=2 will be plotted on top of zorder=1)
f = plt.figure() # create a figure
ax = f.add_subplot( ... ) # create an axis in the figure f
ax.plot(..., zorder=0)
grid_duomo.plot(ax=ax, ..., zorder=1)
# you can then continue to add more axes to the same figure using
# f.add_subplot() or f.add_axes()
(if this is unclear, maybe check the quick_start guide of matplotlib? )
I have two bars which I want to mirror. I have the following code
bar1 = df['nt'].value_counts().plot.barh()
bar2 = df1['nt'].value_counts().plot.barh()
bar1.set_xlim(bar1.get_xlim()[::-1])
# bar1.yaxis.tick_right()
But somehow not only the bar1 flips to the left(third line), but also the bar2. The same happening with the commented 4th line. Why is that? How to do it right then?
df...plot.barh()doesn't return bars nor a barplot. It returns theaxwhich indicates the subplot where the barplot was added. As both barplots are created onto the same subplot,set_xlim` etc. will act on that same subplot. This blogpost might be helpful.
To get two barplots, one from the left and one from the right, you could create a "twin" y -axis and then drawing one bar plot using the lower x-axis and the other user the upper x-axis. To make things clearer, the tick labels can be colored the same as the bars. To avoid overlapping bars, the x limits should be at least the maximum of the sum of the two value_counts.
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
df = pd.DataFrame({'nt': np.random.choice([*'abcdefhij'], 50)})
df1 = pd.DataFrame({'nt': np.random.choice([*'abcdefhij'], 50)})
max_sum_value_counts = df.append(df1).value_counts().max()
fig, ax = plt.subplots(figsize=(12, 5))
df['nt'].value_counts(sort=False).sort_index().plot.barh(ax=ax, color='purple')
ax.set_xlim(0, max_sum_value_counts + 1)
ax.tick_params(labelcolor='purple')
ax1 = ax.twiny()
df1['nt'].value_counts(sort=False).sort_index().plot.barh(ax=ax1, color='crimson')
ax1.set_xlim(max_sum_value_counts + 1, 0)
ax1.tick_params(labelcolor='crimson', labelright=True, labelleft=False)
ax1.invert_yaxis()
plt.show()
Trying to plot linear regression-plot with Seaborn and I am ending up having this:
and under it these empty plots:
I don't need the last 3 small subplots, or at least how to get them plotted correctly, with the main first 3 subplots above?
Here is the code I used:
fig, axes = plt.subplots(3, 1, figsize=(12, 15))
for col, ax in zip(['gross_sqft_thousands','land_sqft_thousands','total_units'], axes.flatten()):
ax.tick_params(axis='x', rotation=85)
ax.set_ylabel(col, fontsize=15)
sns.jointplot(x="sale_price_millions", y=col, data=clean_df, kind='reg', joint_kws={'line_kws':{'color':'cyan'}}, ax=ax)
fig.suptitle('Sale Price vs Continuous Variables', position=(.5,1.02), fontsize=20)
fig.tight_layout()
fig.show()
I have two dataframe with the same columns but different content.
I have plotted dffinal data frame. now I want to plot another dataframe dffinal_no on the same diagram to be comparable.
for example one bar chart in blue colour, and the same bar chart with another colour just differentiating in y-axis.
This is part of the code in which I have plotted the first data frame.
dffinal = df[['6month','final-formula','numPatients6month']].drop_duplicates().sort_values(['6month'])
ax=dffinal.plot(kind='bar',x='6month', y='final-formula')
import matplotlib.pyplot as plt
ax2 = ax.twinx()
dffinal.plot(ax=ax2,x='6month', y='numPatients6month')
plt.show()
Now imagine I have another dffinal_no data frame with the same columns, how can I plot it in the same diagram?
This is my first diagram which I plotted, I want the other bar chart on this diagram with another color.
so the answer of #Mohamed Thasin ah is somehow what I want, except that the right y-axis is not correct.
I want both data frame be based on (6month, final-formula) but the right y-axis is just showing number of patients, as an information for the user.
Actually, I DO NOT want the first df based on final-fomula and the second df be based on NumberPatients.
Update1 jast as a refrence how it looks like my data frame
dffinal = df[['6month','final-formula','numPatients6month']].drop_duplicates().sort_values(['6month'])
nocidffinal = nocidf[['6month','final-formula','numPatients6month']].drop_duplicates().sort_values(['6month'])
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax1.set_ylabel('final-formula')
ax2.set_ylabel('numPatients6month')
width=0.4
nocidffinal=nocidffinal.set_index('6month').sort_index()
dffinal=dffinal.set_index('6month').sort_index()
nocidffinal['final-formula'].plot(kind='bar',color='green',ax=ax1,width=width,position=0)
dffinal['numPatients6month'].plot(kind='bar',color='red',ax=ax2,width=width,position=1)
dffinal content
,6month,final-formula,numPatients6month
166047.0,1,7.794117647058823,680
82972.0,2,5.720823798627003,437
107227.0,3,5.734767025089606,558
111330.0,4,4.838709677419355,434
95591.0,5,3.3707865168539324,534
95809.0,6,3.611738148984198,443
98662.0,7,3.5523978685612785,563
192668.0,8,2.9978586723768736,467
89460.0,9,0.9708737864077669,515
192585.0,10,2.1653543307086616,508
184325.0,11,1.727447216890595,521
85068.0,12,1.0438413361169103,479
nocidffinal
,6month,final-formula,numPatients6month
137797.0,1,3.5934291581108826,974
267492.0,2,2.1705426356589146,645
269542.0,3,2.2106631989596877,769
271950.0,4,2.0,650
276638.0,5,1.5587529976019185,834
187719.0,6,1.9461077844311379,668
218512.0,7,1.1406844106463878,789
199830.0,8,0.8862629246676514,677
269469.0,9,0.3807106598984772,788
293390.0,10,0.9668508287292817,724
254783.0,11,1.2195121951219512,738
300974.0,12,0.9695290858725761,722
to compare two data frame result with bar plot one way you could try is concatenating two data frames and adding hue.
For example consider below df it contains same x and y columns in both df's and wanna compare this values. to achieve this simply add hue column for each df with differentiating constant like below.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df1=pd.DataFrame({'x':[1,2,3,4,5],'y':[10,2,454,121,34]})
df2=pd.DataFrame({'x':[4,1,2,5,3],'y':[54,12,65,12,8]})
df1['hue']=1
df2['hue']=2
res=pd.concat([df1,df2])
sns.barplot(x='x',y='y',data=res,hue='hue')
plt.show()
The result should looks like below:
To get two y-axis try this method,
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax1.set_ylabel('final-formula')
ax2.set_ylabel('numPatients6month')
width=0.4
df1=df1.set_index('x').sort_index()
df2=df2.set_index('x').sort_index()
df1['y'].plot(kind='bar',color='blue',ax=ax1,width=width,position=1)
df2['y'].plot(kind='bar',color='green',ax=ax2,width=width,position=0)
plt.show()
with actual input:
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax1.set_ylabel('final-formula')
ax2.set_ylabel('numPatients6month')
width=0.4
df1=df1.set_index('6month').sort_index()
df2=df2.set_index('6month').sort_index()
df1['final-formula'].plot(kind='bar',color='blue',ax=ax1,width=width,position=1)
df2['numPatients6month'].plot(kind='bar',color='green',ax=ax2,width=width,position=0)
plt.show()