Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

## [Matplotlib-users] Dual x-axes with transformation

 [Matplotlib-users] Dual x-axes with transformation From: Sarah Graves - 2010-05-26 11:54:28 ```Hi, I've made a matplotlib plot with frequency on the x-axis, and I would like to add an additional x-axis at the top that is measured in wavelength , i.e. wavelength = 3e8 / frequency Is there anyway to do this transformation automatically in matplotlib? I tried to give a transformation argument to the ax.twin() axes_grid command, as shown in the axes_grid parasite_simple2.py example, but I've not managed to get this to work with a transformation more complicated than a scaling by a constant factor. I tried looking at the matplotlib.transforms documentation but I couldn't see a way to do this transformation there. I'm not sure I understood it very well though. I can't simply use the twiny( ) command and manually set the limits as the wavelength ticks will not occur at the points corresponding to the correct frequency. At the moment I am using the twin() command, and then I manually choose a sensible set of tickvalues I want in wavelength units, calculate the corresponding frequency values, and then set the tick locations to be the frequency values and the tick labels to be the wavelength values. Thanks, Sarah Example code: import numpy as np import matplotlib from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost import matplotlib.pyplot as plt #create xaxis range of values -- 200 -- 1000 Ghz xvals = np.arange(199.9, 999.9, 0.1) #make some test data data = np.sin(0.03*xvals) #set up the figure fig = plt.figure() ax = SubplotHost(fig, 111) fig.add_subplot(ax) ax2 = ax.twin() #plot data ax.plot(xvals, data) ax.set_xlim(200.0, 1000.0) #set up ax2 with chosen values wavelength_labels = np.array([0.4, 0.6, 0.8,1.0,1.2, 1.4]) #in mm frequency_points = 3e2/wavelength_labels #in GHz ax2.set_xticks(frequency_points) ax2.set_xticklabels(wavelength_labels) ax2.set_xlabel('Wavelength (mm)') ax.set_xlabel('Frequency (GHz)') plt.show() ```

 [Matplotlib-users] Dual x-axes with transformation From: Sarah Graves - 2010-05-26 11:54:28 ```Hi, I've made a matplotlib plot with frequency on the x-axis, and I would like to add an additional x-axis at the top that is measured in wavelength , i.e. wavelength = 3e8 / frequency Is there anyway to do this transformation automatically in matplotlib? I tried to give a transformation argument to the ax.twin() axes_grid command, as shown in the axes_grid parasite_simple2.py example, but I've not managed to get this to work with a transformation more complicated than a scaling by a constant factor. I tried looking at the matplotlib.transforms documentation but I couldn't see a way to do this transformation there. I'm not sure I understood it very well though. I can't simply use the twiny( ) command and manually set the limits as the wavelength ticks will not occur at the points corresponding to the correct frequency. At the moment I am using the twin() command, and then I manually choose a sensible set of tickvalues I want in wavelength units, calculate the corresponding frequency values, and then set the tick locations to be the frequency values and the tick labels to be the wavelength values. Thanks, Sarah Example code: import numpy as np import matplotlib from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost import matplotlib.pyplot as plt #create xaxis range of values -- 200 -- 1000 Ghz xvals = np.arange(199.9, 999.9, 0.1) #make some test data data = np.sin(0.03*xvals) #set up the figure fig = plt.figure() ax = SubplotHost(fig, 111) fig.add_subplot(ax) ax2 = ax.twin() #plot data ax.plot(xvals, data) ax.set_xlim(200.0, 1000.0) #set up ax2 with chosen values wavelength_labels = np.array([0.4, 0.6, 0.8,1.0,1.2, 1.4]) #in mm frequency_points = 3e2/wavelength_labels #in GHz ax2.set_xticks(frequency_points) ax2.set_xticklabels(wavelength_labels) ax2.set_xlabel('Wavelength (mm)') ax.set_xlabel('Frequency (GHz)') plt.show() ```
 Re: [Matplotlib-users] Dual x-axes with transformation From: Jae-Joon Lee - 2010-05-26 14:08:19 ```You need to define your own transform. And the best way is to read through the transforms.py. Here is a modified version of your example that uses a custom transform. However, often you may need to use a custom locator also for this kind of transform. HTH, -JJ from matplotlib.transforms import Transform, BlendedGenericTransform, IdentityTransform c = 3.e2 class Freq2WavelengthTransform(Transform): input_dims = 1 output_dims = 1 is_separable = False has_inverse = True def transform(self, tr): return c/tr def inverted(self): return Wavelength2FreqTransform() class Wavelength2FreqTransform(Freq2WavelengthTransform): def inverted(self): return Freq2WavelengthTransform() import matplotlib.pyplot as plt from mpl_toolkits.axes_grid.parasite_axes import SubplotHost aux_trans = BlendedGenericTransform(Freq2WavelengthTransform(), IdentityTransform()) fig = plt.figure(2) ax_GHz = SubplotHost(fig, 1,1,1) fig.add_subplot(ax_GHz) ax_GHz.set_xlabel("Frequency (GHz)") import numpy as np xvals = np.arange(199.9, 999.9, 0.1) #make some test data data = np.sin(0.03*xvals) ax_mm = ax_GHz.twin(aux_trans) ax_mm.set_xlabel('Wavelength (mm)') ax_mm.set_viewlim_mode("transform") ax_mm.axis["right"].toggle(ticklabels=False) ax_GHz.plot(xvals, data) ax_GHz.set_xlim(200, 1000) plt.draw() plt.show() On Wed, May 26, 2010 at 7:24 AM, Sarah Graves wrote: > Hi, > > I've made a matplotlib plot with frequency  on the x-axis, and I would > like to add an additional x-axis at the top that is measured in > wavelength , i.e. wavelength = 3e8 / frequency > > Is there anyway to do this transformation automatically in matplotlib? > > I tried to give a transformation argument to the ax.twin() axes_grid > command, as shown in the axes_grid parasite_simple2.py example,  but > I've not managed to get this to work with a transformation more > complicated than a scaling by a constant factor. I tried looking at the > matplotlib.transforms documentation but I couldn't see a way to do this > transformation there. I'm not sure I understood it very well though. I > can't simply use the twiny( ) command and manually set the limits as the > wavelength ticks will not occur at the points corresponding to the > correct frequency. > > At the moment I am using the twin() command, and then I  manually choose > a sensible set of tickvalues  I want in wavelength units,  calculate the > corresponding frequency values, and then set the tick locations to be > the frequency values and the tick labels to be the wavelength values. > > Thanks, > Sarah > > Example code: > import numpy as np > import matplotlib > from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost > import matplotlib.pyplot as plt > #create xaxis range of values -- 200 -- 1000 Ghz > xvals = np.arange(199.9, 999.9, 0.1) > #make some test data > data = np.sin(0.03*xvals) > #set up the figure > fig = plt.figure() > ax = SubplotHost(fig, 111) > fig.add_subplot(ax) > ax2 = ax.twin() > #plot data > ax.plot(xvals, data) > ax.set_xlim(200.0, 1000.0) > #set up ax2 with chosen values > wavelength_labels = np.array([0.4, 0.6, 0.8,1.0,1.2, 1.4]) #in mm > frequency_points = 3e2/wavelength_labels #in GHz > ax2.set_xticks(frequency_points) > ax2.set_xticklabels(wavelength_labels) > ax2.set_xlabel('Wavelength (mm)') > ax.set_xlabel('Frequency (GHz)') > plt.show() > > > > > > ------------------------------------------------------------------------------ > > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > ```
 Re: [Matplotlib-users] Dual x-axes with transformation From: Sarah Graves - 2010-05-26 14:35:08 ```Brilliant, that worked perfectly! Thanks very much, Sarah Jae-Joon Lee wrote: > You need to define your own transform. And the best way is to read > through the transforms.py. Here is a modified version of your example > that uses a custom transform. > > However, often you may need to use a custom locator also for this kind > of transform. > > HTH, > > -JJ > > from matplotlib.transforms import Transform, BlendedGenericTransform, > IdentityTransform > > c = 3.e2 > > class Freq2WavelengthTransform(Transform): > input_dims = 1 > output_dims = 1 > is_separable = False > has_inverse = True > > def transform(self, tr): > return c/tr > > def inverted(self): > return Wavelength2FreqTransform() > > > class Wavelength2FreqTransform(Freq2WavelengthTransform): > def inverted(self): > return Freq2WavelengthTransform() > > > import matplotlib.pyplot as plt > from mpl_toolkits.axes_grid.parasite_axes import SubplotHost > > > aux_trans = BlendedGenericTransform(Freq2WavelengthTransform(), > IdentityTransform()) > > fig = plt.figure(2) > > ax_GHz = SubplotHost(fig, 1,1,1) > fig.add_subplot(ax_GHz) > ax_GHz.set_xlabel("Frequency (GHz)") > > import numpy as np > xvals = np.arange(199.9, 999.9, 0.1) > #make some test data > data = np.sin(0.03*xvals) > > ax_mm = ax_GHz.twin(aux_trans) > ax_mm.set_xlabel('Wavelength (mm)') > ax_mm.set_viewlim_mode("transform") > ax_mm.axis["right"].toggle(ticklabels=False) > > ax_GHz.plot(xvals, data) > ax_GHz.set_xlim(200, 1000) > > plt.draw() > plt.show() > > > > > On Wed, May 26, 2010 at 7:24 AM, Sarah Graves wrote: > >> Hi, >> >> I've made a matplotlib plot with frequency on the x-axis, and I would >> like to add an additional x-axis at the top that is measured in >> wavelength , i.e. wavelength = 3e8 / frequency >> >> Is there anyway to do this transformation automatically in matplotlib? >> >> I tried to give a transformation argument to the ax.twin() axes_grid >> command, as shown in the axes_grid parasite_simple2.py example, but >> I've not managed to get this to work with a transformation more >> complicated than a scaling by a constant factor. I tried looking at the >> matplotlib.transforms documentation but I couldn't see a way to do this >> transformation there. I'm not sure I understood it very well though. I >> can't simply use the twiny( ) command and manually set the limits as the >> wavelength ticks will not occur at the points corresponding to the >> correct frequency. >> >> At the moment I am using the twin() command, and then I manually choose >> a sensible set of tickvalues I want in wavelength units, calculate the >> corresponding frequency values, and then set the tick locations to be >> the frequency values and the tick labels to be the wavelength values. >> >> Thanks, >> Sarah >> >> Example code: >> import numpy as np >> import matplotlib >> from mpl_toolkits.axes_grid1.parasite_axes import SubplotHost >> import matplotlib.pyplot as plt >> #create xaxis range of values -- 200 -- 1000 Ghz >> xvals = np.arange(199.9, 999.9, 0.1) >> #make some test data >> data = np.sin(0.03*xvals) >> #set up the figure >> fig = plt.figure() >> ax = SubplotHost(fig, 111) >> fig.add_subplot(ax) >> ax2 = ax.twin() >> #plot data >> ax.plot(xvals, data) >> ax.set_xlim(200.0, 1000.0) >> #set up ax2 with chosen values >> wavelength_labels = np.array([0.4, 0.6, 0.8,1.0,1.2, 1.4]) #in mm >> frequency_points = 3e2/wavelength_labels #in GHz >> ax2.set_xticks(frequency_points) >> ax2.set_xticklabels(wavelength_labels) >> ax2.set_xlabel('Wavelength (mm)') >> ax.set_xlabel('Frequency (GHz)') >> plt.show() >> >> >> >> >> >> ------------------------------------------------------------------------------ >> >> _______________________________________________ >> Matplotlib-users mailing list >> Matplotlib-users@... >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >> >> ```