I am plotting two dataframes in the same chart: the USDEUR exchange rate and the 3-day moving average.
df.plot(ax=ax, linewidth=1)
rolling_mean.plot(ax=ax, linewidth=1)
Both dataframes are labelled "Value" so I would like to customize that:
I tried passing the label option but that didn't work, as it seems that this option is exclusive to matplotlib.axes.Axes.plot and not to pandas.DataFrame.plot. So I tried using axes instead, and passing each label:
ax.plot(df, linewidth=1, label='FRED/DEXUSEU')
ax.plot(rolling_mean, linewidth=1, label='3-day SMA')
However now the legend is not showing up at all unless I explicitly call ax.legend() afterwards.
Is it possible to plot the dataframes while passing custom labels without the need of an additional explicit call?
When setting a label using df.plot() you have to specifiy the data which is being plotted:
fig, (ax1, ax2) = plt.subplots(1,2)
df = pd.DataFrame({'Value':np.random.randn(10)})
df2 = pd.DataFrame({'Value':np.random.randn(10)})
df.plot(label="Test",ax=ax1)
df2.plot(ax=ax1)
df.plot(y="Value", label="Test",ax=ax2)
df2.plot(y="Value", ax=ax2)
ax1.set_title("Reproduce problem")
ax2.set_title("Possible solution")
plt.show()
Which gives:
Update: It appears that there is a difference between plotting a dataframe, and plotting a series. When plotting a dataframe, the labels are taken from the column names. However, when specifying y="Value" you are then plotting a series, which then actually uses the label argument.
Related
I am using geoplot's kdeplot function to display Kernel Density maps (aka heatmaps), for different periods of time.
I have a code that looks like this:
fig, axs = plt.subplots(n_rows, n_cols, figsize=(20,10))
for ax, t in zipped(axs.flatten(), periods):
# df is a GeoPandas dataframe
data = df.loc[(df['period'] == t), ['id', 'geometry']]
# heatmap plot
gplt.kdeplot(
data,
clip=africa.geometry,
cmap='Reds',
shade=True,
cbar=True,
ax=ax)
gplt.polyplot(africa, ax=ax, zorder=1)
ax.set_title(int(t))
It outputs the following image
i would like instead to be able to define a common scale for my entire dataset (regardless of the time), which I can then use in kdeplot and as a unique legend for my subplots.
I know that my data have different density in different years, but I am trying to find a sort of common values that can be used for each of them.
I thought the levels parameter would be what I am looking for (i.e. using the same iso-proportions of the density for my periods, e.g. [0.2,0.4,0.6,0.8,1]).
However, when I use it in combination with cbar=True to display the legends, the values of each legend is different from the other legends (and from the levels vector).
Am I doing something wrong?
If not, do I need to manually set the cbar?
I am trying to find a way to apply the shared axes parameters of subplot() to every other plot in a series of subplots.
I've got the following code, which uses data from RPM4, based on rows in fpD
fig, ax = plt.subplots(2*(fpD['name'].count()), sharex=True, figsize=(6,fpD['name'].count()*2),
gridspec_kw={'height_ratios':[5,1]*fpD['name'].count()})
for i, r in fpD.iterrows():
RPM4[RPM4['name'] == RPM3.iloc[i,0]].plot(x='date', y='RPM', ax=ax[(2*i)], legend=False)
RPM4[RPM4['name'] == RPM3.iloc[i,0]].plot(kind='area', color='lightgrey', x='date', y='total', ax=ax[(2*i)+1],
legend=False,)
ax[2*i].set_title('test', fontsize=12)
plt.tight_layout()
Which produces an output that is very close to what I need. It loops through the 'name' column in a table and produces two plots for each, and displays them as subplots:
As you can see, the sharex parameter works fine for me here, since I want all the plots to share the same axis.
However, what I'd really like is for all the even-numbered (bigger) plots to share the same y axis, and for the odd-numbered (small grey) plots to all share a different y axis.
Any help on accomplishing this is much appreciated, thanks!
I use Seaborn/Matplotlib to display different outputs (time and distance for example) for different parameters. I would like to associate the two outputs on the same plot, thus I use seaborn's satplot and barplot.
My problem is I don't get the expected display. The graph is here but some noisy extra axis appear.
I'm running the following code
ax = plt.subplot(311)
ax2 = ax.twinx()
data = sns.load_dataset("tips")
sns.barplot(ax=ax, x="day",y="total_bill", hue="size" , data=data, ci=None)
ax.set_yscale("log")
sns.catplot(data=data, x="day", y="tip", ax=ax2, hue="size", kind="swarm", palette="bright")
And I have the following result :
Could you help me to remove this extra axis ? It is especially inconvenient when having multiple subplots.
The extra axis you see is the one returned by the catplot. To get rid of it, you can add the following line after the sns.catplot(...) where the index 2 refers to the count of the figure.
plt.close(2)
To test that, if you use plt.close(1), it will remove the main figure containing bar chart
The extra axes you see is the catplot you create. catplot is a figure-level function (i.e. it creates its own figure); and hence does not really have an ax argument. One could see it as bug that it still allows for it. What you would probably like to do is to create a sns.swarmplot instead, which does have the ax argument.
I can clear the text of the xlabel in a Pandas plot with:
plt.xlabel("")
Instead, is it possible to hide the label?
May be something like .xaxis.label.set_visible(False).
From the Pandas docs -
The plot method on Series and DataFrame is just a simple wrapper around plt.plot():
This means that anything you can do with matplolib, you can do with a Pandas DataFrame plot.
pyplot has an axis() method that lets you set axis properties. Calling plt.axis('off') before calling plt.show() will turn off both axes.
df.plot()
plt.axis('off')
plt.show()
plt.close()
To control a single axis, you need to set its properties via the plot's Axes. For the x axis - (pyplot.axes().get_xaxis().....)
df.plot()
ax1 = plt.axes()
x_axis = ax1.axes.get_xaxis()
x_axis.set_visible(False)
plt.show()
plt.close()
Similarly to control an axis label, get the label and turn it off.
df.plot()
ax1 = plt.axes()
x_axis = ax1.axes.get_xaxis()
x_axis.set_label_text('foo')
x_label = x_axis.get_label()
##print isinstance(x_label, matplotlib.artist.Artist)
x_label.set_visible(False)
plt.show()
plt.close()
You can also get to the x axis like this
ax1 = plt.axes()
x_axis = ax1.xaxis
x_axis.set_label_text('foo')
x_axis.label.set_visible(False)
Or this
ax1 = plt.axes()
ax1.xaxis.set_label_text('foo')
ax1.xaxis.label.set_visible(False)
DataFrame.plot
returns a matplotlib.axes.Axes or numpy.ndarray of them
so you can get it/them when you call it.
axs = df.plot()
.set_visible() is an Artist method. The axes and their labels are Artists so they have Artist methods/attributes as well as their own. There are many ways to customize your plots. Sometimes you can find the feature you want browsing the Gallery and Examples
You can remove axis labels and ticks using xlabel= or ylabel= arguments in the plot() call. For example, to remove the xlabel, use xlabel='':
df.plot(xlabel='');
To remove the x-axis ticks, use xticks=[] (for y-axis ticks, use yticks=):
df.plot(xticks=[]);
To remove both:
df.plot(xticks=[], xlabel='');
I have two dataframes, with unique x and y coordinates, and I want to plot them in the same figure.
I am now plotting two dataframes in same figure as such:
plt.plot(df1['x'],df1['y'])
plt.plot(df2['x'],df2['y'])
plt.show
However, pandas also has plotting functionality.
df.plot()
How could I achieve the same as my first example but use the pandas functionality?
To plot all columns against the index as line plots.
ax = df1.plot()
df2.plot(ax=ax)
A single pandas.DataFrame.plot (not subplots=True) returns a matplotlib.axes.Axes, which you can then pass to the second dataframe.
To plot specific columns as x and y. Specifying x and y is required for scatter plots (kind='scatter').
ax = df1.plot(x='Lat', y='Lon', figsize=(8, 8))
df2.plot(ax=ax, x='Lat', y='Lon')