I am trying to put together a plot that incorporates multiple different data frames that share a common index. Despite setting all the X-axes to the same labels and ticks they still don't lineup within the as be seen with the top x-axis. Causing whitespace on the right y-axis.
Output Graph Here
fig,axe=plt.subplots()
axe.set_xlabel('Total Collectors in Array')
axe.set_ylabel('Energy Generated (MJ)')
plt.xticks(ticks=df.index.values,labels=df.index.values)
axe.plot(df,label= label_list,zorder=0,marker='o')
labelLines(axe.get_lines())
ax3=axe.twiny()
ax2=axe.twinx()
ax3.plot(df3,label=label_list,zorder=1,linewidth=1,linestyle='--')
ax3.axes.xaxis.set_visible(True)
labelLines(ax3.get_lines(),align=False,xvals=[1.5]*10,zorder=2.5)
ax2.set_ylabel('DHW Draw Rate')
ax2.imshow(df2,zorder=2,
cmap='CMRmap',alpha=0.3,origin='lower')
a=ax2.get_xticks().tolist()
label_list1=label_list[:]
ax2.set(xticks=x_lab,xticklabels=x_lab,yticks=y_ticks,yticklabels=label_list1)
fig.tight_layout()
plt.show()
Related
I have the following code, which almost does what I need it to do. I am graphing the importance of each feature for two different models on the same graph for comparison. I can't seem to get them to show side by side as two separate bars. I am fairly new to python and brand new to this forum. here is the code:
def plot_importances1(model1, feature_names1, label1, model2=None,feature_names2=None, label2=None):
if model2 is None:
importances1 = model1.feature_importances_
indices1 = np.argsort(importances1)
plt.figure(figsize=(8, 8)) # Set figure size
# plot the first list of feature importances as a horizontal bar chart
plt.barh(range(len(indices1)), importances1[indices1], color="violet", align="center", label=label1)
# set the y-axis tick labels to be the feature names
plt.yticks(range(len(indices1)), [feature_names1[i] for i in indices1])
else:
importances1 = model1.feature_importances_
indices1 = np.argsort(importances1)
importances2 = model2.feature_importances_
indices2 = np.argsort(importances2)
plt.figure(figsize=(8, 8)) # Set figure size
# plot the first list of feature importances as a horizontal bar chart
plt.barh(range(len(indices1)), importances1[indices1], color="violet", align="center", label=label1)
# plot the second list of feature importances as a horizontal bar chart
plt.barh(range(len(indices2)), importances2[indices2], color="orange", align="center", label=label2)
# set the y-axis tick labels to be the feature names
plt.yticks(range(len(indices1)), [feature_names1[i] for i in indices1])
# add a title and x- and y-axis labels
plt.title("Feature Importances")
plt.xlabel("Relative Importance")
plt.ylabel("Feature")
# add a legend to the plot
plt.legend()
# set the tick locations and labels for the first bar graph
plt.gca().tick_params(axis='x', which='both', length=0)
plt.gca().xaxis.set_ticks_position('top')
plt.gca().xaxis.set_label_position('top')
# set the tick locations and labels for the second bar graph
plt.twinx()
plt.gca().tick_params(axis='x', which='both', length=0)
plt.gca().xaxis.set_ticks_position('bottom')
plt.gca().xaxis.set_label_position('bottom')
plt.show()
Then I call the function:
plot_importances1(
dTree_treat_out,
list(X1_train),
"Outliers present",
dTree,
list(X_train),
"No outliers",
)
The two bars are both showing, but I can't get them to separate completely and I am getting this error:
Output for the code
I have ran several version of this, including one that does not return the matplotlib error. The problem with the other function definitions that I have is that the bars are stacked and I can't see both of them. If I knew how to make one less opaque? I am super stuck. I so not want them stacked, I need the first one to be its own graph with the second one NEXT to it, not overlaying or stacked on top, similar to the image I uploaded, but the bars need to be completely separated.
Any input to fix this issue will be greatly appreciated.
I am using Plotly and Python to chart a bar plot. On the x-axis, Plotly arranges the values from each trace around the centre of the tick mark.
This is what I am getting now:
I would like to have the data points (and labels) in between the tick marks. In the example chart, this would mean all the bars centered around 0-2kw would move left of the first tick and the label centered, all the bars around 2-4kw would move between the first and second ticks and the label centered, etc..
I am using tickmode=array, ticktext as an array and also set tickson=boundaries, but it's still the same.
Is there a way to do this?
(Not sure if this makes any difference but there are multiple charts in subplots)
Answering my own question.
Normally setting tickon=boundaries should do the trick, but it doesn't seem to work in conjunction with tickmode=array and ticktext.
The solution for me was to create the labels array and provide it to the bar chart as the x parameter, something similar to this:
fig = go.Figure(data=go.Bar(name='Trace1', x=['0-2kw', '2-4kw', '4-6kw', '6-8kw'], y=[0.2, 0.2, 0.2, 0.4]))
fig.update_xaxes(showgrid=True, tickson='boundaries')
Doing this in my code now the data bars are in between the grid lines:
I am using matplotlib to create multiple bar plots using the following code:
fig = plt.figure(figsize=(4, 4))
plt.barh(y=y, width=width, height=0.5)
plt.yticks(y, labels)
plt.xlabel("Contribution")
plt.tight_layout()
plt.show()
Since the length of my y-ticks labels can vary, the plot can get squeezed together as in the case below:
In other cases the plot looks fine:
Now, I was wondering, if there is an option in matplotlib to keep the plot size constant, but scale the figure size automatically (in horizontal direction)? My goal is that the plot size stays always the same, independent of the y-label length (because they vary inbetween plots). Thank you!
The project I am doing requires code to plot more than 300 candlestick charts in several figures using mplfinance library. I am aware that this can only be done using external axes method as it provides more flexibilities and can plot unlimited charts theoretically.
The current code I am using is as below, the charts plotted can be seen below:
import mplfinance as mpf
s = mpf.make_mpf_style(base_mpf_style='yahoo', rc={'font.size': 6})
fig = mpf.figure(figsize=(34, 13.2), style=s, tight_layout=True)
ax_p = fig.add_subplot(n_rows, n_cols, pos_price)
ax_v = fig.add_subplot(n_rows, n_cols, pos_vol, sharex=ax_p)
fig, ax_list = mpf.plot(resampled_df, type='candle', ax=ax_p, volume=ax_v, show_nontrading=False,
datetime_format='%a %d-%m-%y', xrotation=0, returnfig=True)
The screenshot of the 6 sample charts from hundreds of charts my code plotted:
The screenshot of the two charts the above code plotted is as below:
As you can see the volume chart was plotted in an individual chart below the candlestick chart. I struggle to find the solution to move the volume into candlestick chart, there is a similar post in mplfinance documentation issue 114 kind of explains how to do this...... but I found it is rather difficult to understand for new ppl to the library like me.
Would highly appreciate it if you could post the detailed code to do this!
Update on 12th Feb 2021:
I modified the code with #Daniel's suggestion, use add_axes() rather than add_subplot() and now the volume is at the bottom of the candlestick chart when plotting multiple charts. Beautiful! Answer accepted.
ax_intra_day_candle = fig.add_axes([x_pos, y_pos, ax_width, ax_height])
ax_intra_day_candle.set_title(title)
ax_intra_day_volume = fig.add_axes([x_pos, y_pos - ax_vol_height, ax_width, ax_vol_height], sharex=ax_intra_day_candle)
mpf.plot(intra_day_df, type='candle', ax=ax_intra_day_candle, volume=ax_intra_day_volume, show_nontrading=False,
datetime_format='%a %m-%d', xrotation=0)
I will assume what you are asking is to have the volume and candlesticks share the same x-axis similar to this image here.
The simplest way to do this is to use fig.add_axes() (instead of fig.add_subplot())
In this way you can control exactly where in the Figure each Axes is placed. You can see this being done in the mplfinance code here.
The basic idea is that you specify the location of each Axes object in terms of a fraction of the total figure, indicating the lower left corner of the Axes, and its width and height.
When you want two Axes objects to touch, with no space between them, you specify the location and width/height accordingly so that the top of the lower Axes and the bottom of the upper Axes exactly meet.
So, for example, to stack two equally sized Axes exactly on top of each other, lets say in the upper left quadrant of the Figure you would have:
# ax = fig.add_axes([left,bottom,width,height])
ax1 = fig.add_axes([0.05,0.75,0.5,0.25])
ax2 = fig.add_axes([0.05,0.50,0.5,0.25])
The 0.05 space to the left allows room for the y-axis labels.
ax1 starts three quarters (0.75) of the way up from the bottom, and stretches half way (0.5) to the right with a height of 0.25 (which takes it to the very top of the Figure).
ax2 starts half way (0.50) up from the bottom, also stretches half way (0.5) across to the right, and has a height of 0.25 taking it exactly to the very bottom of ax1.
HTH
Here is a more specific example, and the result. Notice how the candles and volume plot together only take up the upper left quadrant of the figure:
fig = mpf.figure(figsize=(8,8),style='yahoo')
ax1 = fig.add_axes([0.05,0.75,0.5,0.25])
ax2 = fig.add_axes([0.05,0.50,0.5,0.25])
mpf.plot(df,type='candle',ax=ax1,volume=ax2)
mpf.show()
No need so long code use the below code
suppose you have volume and data for plotting in a chart using mplfinance
mpf.plot(data,type='candle',style='yahoo',volume=True)
I'm attempting to plot a few subplots. The issue that I'm running into is in labeling the x-axis for each plot since they're all different.
The variables relHazardRate and relHazardFICO are dataframes of size 50 X 2
I attempting to plot the below I'm unable to show the x-axis tick marks (i.e. relHazardRate is a variable ranging from 3% to 6%, and relHazardFICO is a variable ranging from 300-850. Each figure in the subplot will have its own x-axis/ticker (there are 8 such plots) and I have provided my logic for 2 as shown below.
fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8)) = plt.subplots(4, 2,figsize=(12,8))
ax1.plot(relHazardRate['orig_coupon'],relHazardRate['Hazard Multiplier']);
ax1.title.set_text('Original Interest Rate');
ax1.set_xticks(range(len(relHazardRate['orig_coupon'])));
ax1.set_xticklabels(relHazardRate['orig_coupon'].to_list())
ax2.plot(relHazardFICO['orig_FICO'],relHazardFICO['Hazard Multiplier'], 'tab:orange');
ax2.title.set_text('Original FICO');
ax2.set_xticks(range(len(relHazardRate['orig_FICO'])));
ax2.set_xticklabels(relHazardRate['orig_FICO'].to_list())
ax.3 through ax.8 follow a similar decleration as the described above
for ax in fig.get_axes():
ax.label_outer()
The subplot that I get is as follows, I want to label each plot with its own x-axis, as shown this is not happening.
Remove the lines with label_outer.
From the docs:
label_outer()
Only show "outer" labels and tick labels.
x-labels are only kept for subplots on the last row; y-labels only for subplots on the first column
Clearly this is what is causing the behaviour you see in your plot