guiqwt icon indicating copy to clipboard operation
guiqwt copied to clipboard

How do I create a plot where the scales of x-axis and y-axis are the same?

Open clsgg opened this issue 2 years ago • 5 comments

clsgg avatar Sep 11 '23 07:09 clsgg

I'm not sure I fully understand what you mean by "the same". Could you please be more specific?

PierreRaybaut avatar Sep 13 '23 13:09 PierreRaybaut

@clsgg If you mean a situation where you have an image that is say 3 times wider than it is tall but you want it to plot as a square then you can adjust the aspect ratio like this (self.plot is the plotter for an ImageDialog):

    def on_set_aspect_ratio(self, force, item):
        """
        on_set_aspect_ratio(): description

        :param force: force description
        :type force: bool

        :param item: the image item
        :type item: image type

        :returns: None
        """
        item = self.get_image_item()
        if item:
            if hasattr(self, "data"):
                if hasattr(item.data, "shape"):
                    h, w = item.data.shape
                    if not hasattr(item, "imageparam"):
                        return
                    if hasattr(item.imageparam, "ymax"):
                        h = (item.imageparam.ymax - item.imageparam.ymin)

                    if hasattr(item.imageparam, "xmax"):
                        w = (item.imageparam.xmax - item.imageparam.xmin )

                    if force:
                        r1 = float(h / w)
                        # h > w
                        r2 = float(w / h)
                        if r1 < r2:
                            r = r1
                        else:
                            r = r2
                        self.plot.set_aspect_ratio(ratio=r)
                        self.plot.replot()
                        self.set_autoscale()

                    else:
                        # print 'resetting to original aspect ratio'
                        self.plot.set_aspect_ratio(ratio=1)
                        self.set_autoscale()

RussBerg avatar Sep 13 '23 15:09 RussBerg

Sorry it wasn't described clearly. I've just started using guiqwt, using its matlab-like syntax for drawing. I want to draw a trajectory, and if the X-axis scale is not equal to the Y-axis scale, the trajectory will deform. If you draw with matlab, you can use the following code:

figure('Name','Trajectory','NumberTitle','on');
plot(pos_E,pos_N);
axis equal;
ylabel('N(m)');xlabel('E(m)');

@RussBerg ,I don't know how to add the code you mentioned when drawing with matlab-like syntax in guiqwt. Is there a way to achieve a similar "axis equal" effect when drawing with matlab-like syntax in guiqwt?

clsgg avatar Sep 14 '23 01:09 clsgg

@PierreRaybaut is going to know the answer to that better than I as I have never used the Matlab like calls, that said it looks like pyplot creates a CurvePlot that does have a methods called set_axis_limits that might allow you to achieve what you want.

RussBerg avatar Sep 14 '23 14:09 RussBerg

@RussBerg: thanks for your help. @clsgg: thanks for the clarification.

What you are looking for is the "lock aspect ratio" feature, which is unfortunately available exclusively for image plots (this limitation will be removed in plotpy, the next major evolution of guiqwt thanks to the unification of curve and image plot internals). In other words, you can't lock aspect ratio using guiqwt.pyplot except if you show an image in the same plot (for instance if you want to draw the trajectory on a background image, if it means anything). If you do so, the aspect ratio will be locked by default and the X/Y axes scales will be the same.

However, if you want to draw only the trajectory, you can still use the guiqwt main API (e.g. by using the ImageDialog object). Here is an example:

# -*- coding: utf-8 -*-

"""
Test for Issue #111

Interactive plotting interface with MATLAB-like syntax
"""

import numpy as np

from guidata.qthelpers import qt_app_context
from guiqwt.plot import ImageDialog
from guiqwt.builder import make


def show_trajectory(x, y, title, **options):
    """Show a trajectory"""
    win = ImageDialog(title, toolbar=True, options=options)
    item = make.mcurve(x, y, "g-")
    plot = win.get_plot()
    plot.add_item(item)
    return win


def test():
    """Test"""
    t = np.linspace(0, 10, 1000)
    x, y = np.cos(t) * t, np.sin(t) * t
    with qt_app_context():
        show_trajectory(x, y, "Trajectory", xlabel="x", ylabel="y").exec()


if __name__ == "__main__":
    test()

PierreRaybaut avatar Sep 14 '23 15:09 PierreRaybaut