Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
clsgg opened this issue Sep 11, 2023 · 5 comments
Open

Comments

@clsgg
Copy link

clsgg commented Sep 11, 2023

No description provided.

@PierreRaybaut
Copy link
Collaborator

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

@RussBerg
Copy link
Collaborator

@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()

@clsgg
Copy link
Author

clsgg commented Sep 14, 2023

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?

@RussBerg
Copy link
Collaborator

@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.

@PierreRaybaut
Copy link
Collaborator

@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()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants