I am building a tool to help with pump selection for pipe systems. It is intended to have a database of pump curve images (which are determined experimentally by the manufacturers and published as images) along with manually-determined coordinates of the corners of the plot region, and overlay a pipe system curve on it to determine operating points, optimize efficiency, etc.
Simulate a pump curve image copied out of a manufacturer's catalog:
pumpcurve = Rasterize[Plot[50 - (q/80)^(5/2), {q, 0, 300},
PlotRange -> {{0, 400}, {0, 60}}, Frame -> True,
FrameLabel -> {{"Total Head, ft", None}, {"Flowrate, gpm", None}},
PlotRangePadding -> None, ImageSize -> 500]]
Get Coordinates for lower left and upper right corners of frame using coordinate tool. On my system they are at {34,35} and {491,317}.
Create a pipe system curve and use Inset to overlay pipecurve on pumpcurve. The yellow background shows the full size of pipecurve. We can locate the lower left corner of the frame easily using the third argument of Inset, which works in the original plot coordinates. However the 4th argument, size, is the difficulty. It is in the coordinates of pumpcurve, and sizes the entire pipecurve, including ticks, axes labels, etc. around the Frame. What I would instead like to do is to size the plot region so that {400,60} in the pipecurve coordinates is at {491, 317} in the pumpcurve coordinates.
With[{
plotLLcorner = {34, 35},
plotURcorner = {491, 317}
},
Module[{pipecurve, size = plotURcorner - plotLLcorner},
pipecurve =
Plot[.001 q^2, {q, 0, 300}, PlotRange -> {{0, 400}, {0, 60}},
PlotStyle -> Red, Frame -> True, FrameStyle -> Blue,
PlotRangePadding -> None, AspectRatio -> Divide @@ Reverse[size]];
Show[
pumpcurve,
Graphics[{Background -> Directive[Opacity[.1], Yellow],
Inset[pipecurve, plotLLcorner, {0, 0}, size]}],
ImageSize -> 500
]
]]
A workaround is to remove everything around the frame, however I have a need to put some alternate scales on the pipecurve to display more information so this is not desirable. Another workaround is to give the user a Locator to manually scale the image, but this is also not desirable. I also tried DynamicLocation but can't get around a circular reference problem.
Is there any way to convert between ImageScaled and plot coordinates so that I could calculate a scale factor, or is there a better way to tackle this problem than using Inset?
size = ImageDimensions@pipecurve / (plotLLcorner - plotURcorner) * Subtract@@@plotrange
, whereplotrange = {{0, 400}, {0, 60}}
. This essentially scales the image such that the ratio between plot-range and inset size is the same as the ratio between the frame size on the image and the image size. $\endgroup$