My code is as follow:
plt.figure(figsize =(15,4) )
sns.set_style("white")
plt.ylim(500,30000)
ax = sns.lineplot(data = df,x = 'date', y = 'number of requests', hue = 'account_name',style="account_name",markers=True, dashes=False)
ax.legend(bbox_to_anchor=[0.94, -0.3], frameon='false', ncol=6)
plt.title('Number of requests over the time', fontsize=20)
plt.xlabel('Date', fontsize=15)
plt.ylabel('Requests', fontsize=15)
plt.grid(True, linestyle = ':')
sns.despine()
but the y ranges are: 5000,10000,15000,20000,25000,30000.
My problem that i have requests starting in very low amount and some are very high as in the screenshot - how can i control the ranges? this graph is not so readable :(
The easiest way is ax.set_ylim(-5000, 25000). As #GigBen commented, the other way to adjust the y-axis tick is to change to log format or create your own.
simple:
ax.set_ylim([-5000,25000])
log style:
ax.yscale('log')
yticks customize:
ax.set_yticks(ax.get_yticks()[::2])
full code:
import matplotlib.pyplot as plt
import seaborn as sns
fig, ax = plt.subplots(figsize=(15,4))
sns.set_style("white")
ax = sns.lineplot(data=df, x='date', y='number of requests', hue="account_name", style="account_name", markers=True, dashes=False)
ax.legend(bbox_to_anchor=[0.94, -0.3], frameon='false', ncol=6)
ax.set_title('Number of requests over the time', fontsize=20)
ax.set_xlabel('Date', fontsize=15)
ax.set_ylabel('Requests', fontsize=15)
ax.grid(True, linestyle = ':')
# update
ax.set_yticks(ax.get_yticks()[::2])
plt.show()
Related
I am creating a Python plot from a dataframe with 3 y-axes. For each y-axis, there are multiple y-values I want to plot. All data sets for the y-axes are plotted against a shared Date x-axis.
The code looks as follows:
df = pd.read_excel (r'test.xlsx', sheet_name='test', engine='openpyxl')
fig, ax = plt.subplots()
ax3 = ax.twinx()
rspine = ax3.spines['right']
rspine.set_position(('axes', 1.15))
ax3.set_frame_on(True)
ax3.patch.set_visible(False)
fig.subplots_adjust(right=0.7)
ax.plot(df['Date'], df['Gas1'], label="Gas1", color='g')
ax.plot(df['Date'], df['Gas2'], label="Gas2", color='b')
ax.plot(df['Date'], df['Gas3'], label="Gas3", marker="o", markersize=2, color='r')
ax.set_xlabel("Date")
ax.set_ylabel("Gas Rate")
ax2 = ax.twinx()
ax2.plot(df['Date'], df['Water1'], label="Water1", color='k')
ax2.plot(df['Date'], df['Water2'], label="Water2", color='y')
ax2.set_ylabel("Water")
ax3.plot(df['Date'], df['Pressure1'], label="Pressure1")
ax3.plot(df['Date'], df['Pressure2'], label="Pressure2")
ax3.set_ylabel("Pressure")
ax.legend()
ax2.legend()
ax3.legend()
plt.show()
The problem I am having is that I want the legends to be outside of the plot, preferably on the right-hand side after the 2nd y-axis. Is this possible? Right now the legends are just overlayed on the plot and not fully visible. I have tried using bbox_to_anchor and loc functions but had no luck. Thank you!
ax.get_legend_handles_labels() collects all the legend handles and their labels. Combining those for each of the axes, a new legend can be created.
bbox_to_anchor= sets an anchor point for the legend, using axes coordinates. loc= needs to be set, to tell which point of the legend's box will get fixed by the anchor.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame({'Date': pd.date_range('20210401', periods=30, freq='D'),
'Gas1': np.random.randn(30).cumsum(),
'Gas2': np.random.randn(30).cumsum(),
'Gas3': np.random.randn(30).cumsum(),
'Water1': np.random.randn(30).cumsum(),
'Water2': np.random.randn(30).cumsum(),
'Pressure1': np.random.randn(30).cumsum(),
'Pressure2': np.random.randn(30).cumsum()})
fig, ax = plt.subplots()
ax3 = ax.twinx()
rspine = ax3.spines['right']
rspine.set_position(('axes', 1.15))
ax3.set_frame_on(True)
ax3.patch.set_visible(False)
fig.subplots_adjust(right=0.7)
ax.plot(df['Date'], df['Gas1'], label="Gas1", color='g')
ax.plot(df['Date'], df['Gas2'], label="Gas2", color='b')
ax.plot(df['Date'], df['Gas3'], label="Gas3", marker="o", markersize=2, color='r')
ax.set_ylabel("Gas Rate")
plt.setp(ax.get_xticklabels(), rotation=45, ha='right')
ax2 = ax.twinx()
ax2.plot(df['Date'], df['Water1'], label="Water1", color='k')
ax2.plot(df['Date'], df['Water2'], label="Water2", color='y')
ax2.set_ylabel("Water")
ax3.plot(df['Date'], df['Pressure1'], label="Pressure1")
ax3.plot(df['Date'], df['Pressure2'], label="Pressure2")
ax3.set_ylabel("Pressure")
handles1, labels1 = ax.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
handles3, labels3 = ax3.get_legend_handles_labels()
ax.legend(handles=handles1 + handles2 + handles3,
labels=labels1 + labels2 + labels3,
bbox_to_anchor=(1.28, 1.02), loc='upper left')
plt.tight_layout()
plt.show()
I am using secondary y-axis and cmap color but when I plot together the color bar cross to my plot
here is my code
fig,ax1=plt.subplots()
ax1 = df_Combine.plot.scatter('Parameter2', 'NPV (MM €)', marker='s', s=500, ylim=(-10,60), c='Lifetime1 (a)', colormap='jet_r', vmin=0, vmax=25, ax=ax1)
graph.axhline(0, color='k')
plt.xticks(rotation=90)
ax2 = ax1.twinx()
ax2.plot(df_Combine_min_select1["CumEnergy1 (kWH)"])
plt.show()
and here is my plotting
anyone can help how to solve this issue?
Thank you
When you let pandas automatically create a colorbar, you don't have positioning options. Therefore, you can create the colorbar in a separate step and provide the pad= parameter to set a wider gap. Default, pad is 0.05, meaning 5% of the width of the subplot.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots()
df_Combine = pd.DataFrame({'Parameter2': np.random.rand(10) * 10,
'NPV (MM €)': np.random.rand(10),
'Lifetime1 (a)': np.random.rand(10) * 25,
})
ax1 = df_Combine.plot.scatter('Parameter2', 'NPV (MM €)', marker='s', s=500, ylim=(-10, 60), c='Lifetime1 (a)',
colormap='jet_r', vmin=0, vmax=25, ax=ax1, colorbar=False)
plt.colorbar(ax1.collections[0], ax=ax1, pad=0.1)
ax2 = ax1.twinx()
ax2.plot(np.random.rand(10))
plt.show()
I wrote a code that read an excel sheet and plots a scatter figure with the following code:
fig, ax = plt.subplots(figsize=(13, 8))
scatter = ax.scatter(df.Date, df.TopAcc, c="blue", s=df.Param / 10000, alpha=0.2)
plot = ax.plot(dfmax.Date, dfmax.TopAcc, marker="o", c="red")
handles, labels = scatter.legend_elements(num=5, prop="sizes", alpha=0.2, color="blue")
legend = ax.legend(handles, labels, loc="lower right", title="# Parameters", )
plt.grid()
plt.show()
And I got the following figure
I have the following issues: How to prevent the legend balls from overlapping?
You can set columnspacing in the legend object:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
fig, ax = plt.subplots(figsize=(13, 8))
df = pd.DataFrame(np.random.rand(20, 2), columns=['x', 'y'])
df['s'] = 5000 * np.random.rand(20)
scatter = ax.scatter(df.x, df.y, c="blue", s=df.s, alpha=0.2)
handles, labels = scatter.legend_elements(num=5, prop="sizes", alpha=0.2, color="blue")
legend = ax.legend(handles, labels, loc="lower right", title="# Parameters", ncol=6, columnspacing=3, bbox_to_anchor=(1, -0.12), frameon=False)
plt.grid()
plt.show()
pyplot is not showing the x-axis on the graph:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('sitka_weather_2014.csv')
df['AKST'] = pd.to_datetime(df.AKST)
df['Dates'] = df['AKST'].dt.strftime('%b %d, %Y')
df.set_index("Dates", inplace= True)
# Plot Data
fig = plt.figure(dpi=256, figsize=(14, 7))
plt.title("Daily high and low temperature - 2014")
df['Max TemperatureF'].plot(linewidth=1, c='blue', label="Max Temperature °F")
df['Min TemperatureF'].plot(linewidth=1, c='red', label="Min Temperature °F")
plt.grid(True)
plt.rc('grid', linestyle=":", linewidth=1, color='gray')
plt.legend(loc='upper left')
plt.xlabel('', fontsize=10)
plt.ylabel("Temperature (°F)", fontsize=10)
plt.tick_params(axis='both', which='major', labelsize=10)
fig.autofmt_xdate(rotation=45)
plt.show()
The x-axis should be the index of the Pandas Dataframe (df) containing the dates.
Your code is actually fine. I tried to run it with the necessary sitka_weather_2014.csv file and it works.
The problem is that you can't see the x-axis because the size of the figure is too big, and thus the description of the x-axis dissapears. Try to scale your figure e.g. by making the dpi smaller:
fig = plt.figure(dpi=100, figsize=(14, 7)) #dpi=100 instead of dpi=256
Or make the labelsize smaller:
plt.tick_params(axis='both', which='major', labelsize=5) #labelsize=5 instead of labelsize=10
Whatever works best for you. But the code is fine and the description of the x-axis is showing.
You have your xlabel value set to null:
plt.xlabel('', fontsize=10)
Want labels for Bollinger Bands (R) ('upper band', 'rolling mean', 'lower band') to show up in legend. But legend just applies the same label to each line with the pandas label for the first (only) column, 'IBM'.
# Plot price values, rolling mean and Bollinger Bands (R)
ax = prices['IBM'].plot(title="Bollinger Bands")
rm_sym.plot(label='Rolling mean', ax=ax)
upper_band.plot(label='upper band', c='r', ax=ax)
lower_band.plot(label='lower band', c='r', ax=ax)
#
# Add axis labels and legend
ax.set_xlabel("Date")
ax.set_ylabel("Adjusted Closing Price")
ax.legend(loc='upper left')
plt.show()
I know this code may represent a fundamental lack of understanding of how matlibplot works so explanations are particularly welcome.
The problem is most probably that whatever upper_band and lower_band are, they are not labeled.
One option is to label them by putting them as column to a dataframe. This will allow to plot the dataframe column directly.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
y =np.random.rand(4)
yupper = y+0.2
ylower = y-0.2
df = pd.DataFrame({"price" : y, "upper": yupper, "lower": ylower})
fig, ax = plt.subplots()
df["price"].plot(label='Rolling mean', ax=ax)
df["upper"].plot(label='upper band', c='r', ax=ax)
df["lower"].plot(label='lower band', c='r', ax=ax)
ax.legend(loc='upper left')
plt.show()
Otherwise you can also plot the data directly.
import matplotlib.pyplot as plt
import numpy as np
y =np.random.rand(4)
yupper = y+0.2
ylower = y-0.2
fig, ax = plt.subplots()
ax.plot(y, label='Rolling mean')
ax.plot(yupper, label='upper band', c='r')
ax.plot(ylower, label='lower band', c='r')
ax.legend(loc='upper left')
plt.show()
In both cases, you'll get a legend with labels. If that isn't enough, I recommend reading the Matplotlib Legend Guide which also tells you how to manually add labels to legends.