Hi James,
Thanks. The box I highlighted is only visible for Spectrogram
s (2D color fill plots) and ticking it does something like your option 2. This option isn’t exposed to Python yet, though, so doing this might be a good first step - in this case we would also need a way to specify in the plot command that the scales should be the same for both axes.
I think that using matplotlib might be an easier way to do this, as there is an aspect='equal'
option you can pass to the plot command, and you can specify the figure size. I tweaked the script in another forum post Export publication quality images - #3 by Nina to plot a workspace with the right aspect ratio and export the figure at the right size (from which it can be printed). Let me know if this helps, or if it would be better to add the ability to do this to Mantidplot:
import numpy as np
import matplotlib.pyplot as plt
CM = 0.393701 # inches
PAD = 1.08 # for axis labels etc
DPI = 170 # change this for your monitor
# ------------------------------------------------------------------------------
# Create figure
# ------------------------------------------------------------------------------
def CreateFigure3D(wksp, title, xlabel, ylabel,
rasterized=False, aspect='auto'):
# prepare data for treatment by matplotlib
# Signal values (really the Z axis)
intensity = wksp.extractY()
xmin, xmax = wksp.readX(0)[0], wksp.readX(0)[-1]
xstep = wksp.readX(0)[1] - xmin
x = np.arange(xmin, xmax + xstep/2.,xstep)
ymin, ymax = wksp.getAxis(1).getMin(), wksp.getAxis(1).getMax()
ystep = wksp.getAxis(1).getValue(1) - ymin
y = np.arange(ymin, ymax + ystep/2.,ystep)
xx, yy = np.meshgrid(x, y)
fig, ax1 = gui_cmd(plt.subplots, 1, 1, dpi=DPI)
ax1.set_aspect(aspect)
cmesh = gui_cmd(ax1.pcolormesh, xx, yy, intensity)
cmesh.set_rasterized(rasterized)
ax1.set_title(title)
ax1.set_xlabel(xlabel)
ax1.set_ylabel(ylabel)
return fig
# ------------------------------------------------------------------------------
# Create a test workspace for demo - replace with actual workspace
# ------------------------------------------------------------------------------
def createTestWS(nPoints):
ws=WorkspaceFactory.create("Workspace2D", XLength=nPoints + 1, YLength=nPoints, NVectors=nPoints)
for i in range(nPoints):
for j in range(nPoints):
ws.dataX(i)[j]=(j - 2.0)*1.0
ws.dataY(i)[j]=(i - 2.0)**2 + (j - 2.0)**2
ws.dataX(i)[nPoints] = 3.0
# X axis
xAxis = ws.getAxis(0)
xAxis.setUnit("Label").setLabel('X', 'cm')
# Y axis
ba = BinEdgeAxis.create(nPoints + 1)
for i in range(nPoints + 1):
ba.setValue(i, (i - 2.0))
ws.replaceAxis(1, ba)
ws.setYUnitLabel("Y")
ws.setYUnit("cm")
return ws
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Get x axis units
# ------------------------------------------------------------------------------
def getXUnits(workspace):
unit = workspace.getAxis(0).getUnit()
label_x = unit.caption()
if label_x != "":
label_x = label_x + " (" + unit.symbol().ascii() + ")"
return label_x
# ------------------------------------------------------------------------------
# Get y axis units
# ------------------------------------------------------------------------------
def getYUnits(workspace):
return workspace.YUnitLabel() + " (" + workspace.YUnit() + ")"
# ------------------------------------------------------------------------------
# Create workspace
histo = createTestWS(5)
# Plot using matplotlib
fig = CreateFigure3D(histo, xlabel=getXUnits(histo),
ylabel=getYUnits(histo), title=histo.name(),
rasterized=False, aspect='equal') # equal aspect ratio
# Set the figure to the correct size.
# Size includes axis labels etc so must include "padding" space for these.
fig.set_size_inches(5*CM + PAD, 5*CM + PAD, forward=True)
fig.tight_layout(pad=PAD)
# To display the plot:
gui_cmd(fig.show)
# To save to file
fig.savefig(filename=r'C:\test_save3d.eps', dpi=fig.dpi)`